diff --git a/.gitignore b/.gitignore deleted file mode 100644 index f41d297a..00000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -032-flutter-web-part1/.firebase/hosting.YnVpbGRcd2Vi.cache diff --git a/001-tik_tok_ui/final/.flutter-plugins-dependencies b/001-tik_tok_ui/final/.flutter-plugins-dependencies deleted file mode 100644 index 25231b8d..00000000 --- a/001-tik_tok_ui/final/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-0.5.0+1/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.2/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-0.5.0+1/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.2/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:49:04.552095","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/001-tik_tok_ui/final/android/app/build.gradle b/001-tik_tok_ui/final/android/app/build.gradle new file mode 100644 index 00000000..97cce324 --- /dev/null +++ b/001-tik_tok_ui/final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.tik_tok_ui" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/001-tik_tok_ui/final/android/app/src/debug/AndroidManifest.xml b/001-tik_tok_ui/final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..bea3057d --- /dev/null +++ b/001-tik_tok_ui/final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/001-tik_tok_ui/final/android/app/src/main/AndroidManifest.xml b/001-tik_tok_ui/final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..282da854 --- /dev/null +++ b/001-tik_tok_ui/final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/final/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java b/001-tik_tok_ui/final/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java new file mode 100644 index 00000000..31def0a5 --- /dev/null +++ b/001-tik_tok_ui/final/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.tik_tok_ui; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/001-tik_tok_ui/final/android/app/src/main/res/drawable/launch_background.xml b/001-tik_tok_ui/final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/001-tik_tok_ui/final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/001-tik_tok_ui/final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/001-tik_tok_ui/final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/final/android/app/src/main/res/values/styles.xml b/001-tik_tok_ui/final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/001-tik_tok_ui/final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/001-tik_tok_ui/final/android/app/src/profile/AndroidManifest.xml b/001-tik_tok_ui/final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..bea3057d --- /dev/null +++ b/001-tik_tok_ui/final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/001-tik_tok_ui/final/android/build.gradle b/001-tik_tok_ui/final/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/001-tik_tok_ui/final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/001-tik_tok_ui/final/android/gradle.properties b/001-tik_tok_ui/final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/001-tik_tok_ui/final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/001-tik_tok_ui/final/android/gradle/wrapper/gradle-wrapper.properties b/001-tik_tok_ui/final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/001-tik_tok_ui/final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/001-tik_tok_ui/final/android/settings.gradle b/001-tik_tok_ui/final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/001-tik_tok_ui/final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/001-tik_tok_ui/final/ios/Flutter/AppFrameworkInfo.plist b/001-tik_tok_ui/final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/001-tik_tok_ui/final/ios/Flutter/Debug.xcconfig b/001-tik_tok_ui/final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/001-tik_tok_ui/final/ios/Flutter/Release.xcconfig b/001-tik_tok_ui/final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/001-tik_tok_ui/final/ios/Runner.xcodeproj/project.pbxproj b/001-tik_tok_ui/final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..3f626825 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/001-tik_tok_ui/final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/001-tik_tok_ui/final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/001-tik_tok_ui/final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/001-tik_tok_ui/final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/final/ios/Runner.xcworkspace/contents.xcworkspacedata b/001-tik_tok_ui/final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/001-tik_tok_ui/final/ios/Runner/AppDelegate.h b/001-tik_tok_ui/final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/001-tik_tok_ui/final/ios/Runner/AppDelegate.m b/001-tik_tok_ui/final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/001-tik_tok_ui/final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/001-tik_tok_ui/final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/final/ios/Runner/Base.lproj/Main.storyboard b/001-tik_tok_ui/final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/final/ios/Runner/Info.plist b/001-tik_tok_ui/final/ios/Runner/Info.plist new file mode 100644 index 00000000..35fbc991 --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + tik_tok_ui + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/001-tik_tok_ui/final/ios/Runner/main.m b/001-tik_tok_ui/final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/001-tik_tok_ui/final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/001-tik_tok_ui/final/lib/home_final_singlefile.dart b/001-tik_tok_ui/final/lib/home_final_singlefile.dart index 69d750f2..6720be9d 100644 --- a/001-tik_tok_ui/final/lib/home_final_singlefile.dart +++ b/001-tik_tok_ui/final/lib/home_final_singlefile.dart @@ -1,243 +1,243 @@ -import 'package:flutter/material.dart'; -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:tik_tok_ui/tik_tok_icons_icons.dart'; - -class HomeSingleFile extends StatelessWidget { - static const double NavigationIconSize = 20.0; - static const double ActionWidgetSize = 60.0; - static const double ActionIconSize = 35.0; - static const double ShareActionIconSize = 25.0; - static const double ProfileImageSize = 50.0; - static const double ActionIconGap = 12.0; - static const double FollowActionIconSize = 25.0; - static const double CreateButtonWidth = 38.0; - - Widget get followingContainer => Container( - height: 100.0, - padding: EdgeInsets.only(bottom: 15.0), - alignment: Alignment(0.0, 1.0), - child: Row( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisSize: MainAxisSize.min, - children: [ - Text('Following'), - Container( - width: 15.0, - ), - Text('For you', - style: TextStyle(fontSize: 17.0, fontWeight: FontWeight.bold)) - ]), - ); - - Widget get videoDescription => Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '@firstjonny', - style: TextStyle(fontWeight: FontWeight.bold), - ), - Container( - height: 10.0, - ), - Text('Video title and some other stuff'), - Container( - height: 10.0, - ), - Row(children: [ - Icon(Icons.music_note, color: Colors.white, size: 15.0), - Container( - width: 10.0, - ), - Text('Artist name', style: TextStyle(fontSize: 12.0)), - Container( - width: 10.0, - ), - Text('Song name', style: TextStyle(fontSize: 12.0)) - ]), - Container( - height: 12.0, - ), - ]), - )); - - Widget get actionsToolbar => Container( - width: 100.0, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - _getProfileVideoAction(), - _getVideoAction(title: '3.2m', icon: TikTokIcons.heart), - _getVideoAction(title: '16.4k', icon: TikTokIcons.chat_bubble), - _getVideoAction( - title: 'Share', icon: TikTokIcons.reply, isShare: true), - _getMusicPlayerAction() - ], - ), - ); - - LinearGradient get musicGradient => LinearGradient(colors: [ - Colors.grey[800], - Colors.grey[900], - Colors.grey[900], - Colors.grey[800] - ], stops: [ - 0.0, - 0.4, - 0.6, - 1.0 - ], begin: Alignment.bottomLeft, end: Alignment.topRight); - - Widget _getMusicPlayerAction() { - return Container( - margin: EdgeInsets.only(top: 10.0), - width: ActionWidgetSize, - height: ActionWidgetSize, - child: Column(children: [ - Container( - padding: EdgeInsets.all(11.0), - height: ProfileImageSize, - width: ProfileImageSize, - decoration: BoxDecoration( - gradient: musicGradient, - borderRadius: BorderRadius.circular(ProfileImageSize / 2)), - child: CachedNetworkImage( - imageUrl: - "https://secure.gravatar.com/avatar/ef4a9338dca42372f15427cdb4595ef7", - placeholder: (context, url) => new CircularProgressIndicator(), - errorWidget: (context, url, error) => new Icon(Icons.error), - ), - ), - ])); - } - - Widget get centerSection => Expanded( - child: Row( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.end, - children: [videoDescription, actionsToolbar])); - - Widget get customCreateIcon => Container( - width: 45.0, - height: 27.0, - child: Stack(children: [ - Container( - margin: EdgeInsets.only(left: 10.0), - width: CreateButtonWidth, - decoration: BoxDecoration( - color: Color.fromARGB(255, 250, 45, 108), - borderRadius: BorderRadius.circular(7.0))), - Container( - margin: EdgeInsets.only(right: 10.0), - width: CreateButtonWidth, - decoration: BoxDecoration( - color: Color.fromARGB(255, 32, 211, 234), - borderRadius: BorderRadius.circular(7.0))), - Center( - child: Container( - height: double.infinity, - width: CreateButtonWidth, - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(7.0)), - child: Icon( - Icons.add, - size: 20.0, - ), - )), - ])); - - Widget get navigationBar => Padding( - padding: EdgeInsets.only(top: 15.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Icon(TikTokIcons.home, color: Colors.white, size: NavigationIconSize), - Icon(TikTokIcons.search, - color: Colors.white, size: NavigationIconSize), - customCreateIcon, - Icon(TikTokIcons.messages, - color: Colors.white, size: NavigationIconSize), - Icon(TikTokIcons.profile, - color: Colors.white, size: NavigationIconSize) - ], - )); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - color: Colors.black, - child: Column( - children: [ - followingContainer, - centerSection, - Opacity( - opacity: 0.1, - child: Container(height: 1.0, color: Colors.grey[300])), - navigationBar, - ], - ), - ), - ); - } - - Widget _getVideoAction({String title, IconData icon, bool isShare = false}) { - return Container( - margin: EdgeInsets.only(top: 15.0), - width: ActionWidgetSize, - height: ActionWidgetSize, - child: Column(children: [ - Icon(icon, - size: isShare ? ShareActionIconSize : ActionIconSize, - color: Colors.grey[300]), - Padding( - padding: EdgeInsets.only(top: isShare ? 5.0 : 2.0), - child: - Text(title, style: TextStyle(fontSize: isShare ? 10.0 : 12.0)), - ) - ])); - } - - Widget _getProfileVideoAction({String pictureUrl}) { - return Stack(children: [ - Container( - margin: EdgeInsets.only(top: 10.0), - width: ActionWidgetSize, - height: ActionWidgetSize, - child: Column(children: [ - Container( - padding: EdgeInsets.all(1.0), - height: ProfileImageSize, - width: ProfileImageSize, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(ProfileImageSize / 2)), - child: CachedNetworkImage( - imageUrl: - "https://secure.gravatar.com/avatar/ef4a9338dca42372f15427cdb4595ef7", - placeholder: (context, url) => new CircularProgressIndicator(), - errorWidget: (context, url, error) => new Icon(Icons.error), - ), - ), - ])), - Positioned( - width: 15.0, - height: 15.0, - bottom: 5, - left: ((ActionWidgetSize / 2) - (15 / 2)), - child: Container( - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(15.0)), - )), - Positioned( - bottom: 0, - left: ((ActionWidgetSize / 2) - (FollowActionIconSize / 2)), - child: Icon(Icons.add_circle, - color: Color.fromARGB(255, 255, 43, 84), - size: FollowActionIconSize)) - ]); - } -} +import 'package:flutter/material.dart'; +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:tik_tok_ui/tik_tok_icons_icons.dart'; + +class HomeSingleFile extends StatelessWidget { + static const double NavigationIconSize = 20.0; + static const double ActionWidgetSize = 60.0; + static const double ActionIconSize = 35.0; + static const double ShareActionIconSize = 25.0; + static const double ProfileImageSize = 50.0; + static const double ActionIconGap = 12.0; + static const double FollowActionIconSize = 25.0; + static const double CreateButtonWidth = 38.0; + + Widget get followingContainer => Container( + height: 100.0, + padding: EdgeInsets.only(bottom: 15.0), + alignment: Alignment(0.0, 1.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.end, + mainAxisSize: MainAxisSize.min, + children: [ + Text('Following'), + Container( + width: 15.0, + ), + Text('For you', + style: TextStyle(fontSize: 17.0, fontWeight: FontWeight.bold)) + ]), + ); + + Widget get videoDescription => Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 20.0), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '@firstjonny', + style: TextStyle(fontWeight: FontWeight.bold), + ), + Container( + height: 10.0, + ), + Text('Video title and some other stuff'), + Container( + height: 10.0, + ), + Row(children: [ + Icon(Icons.music_note, color: Colors.white, size: 15.0), + Container( + width: 10.0, + ), + Text('Artist name', style: TextStyle(fontSize: 12.0)), + Container( + width: 10.0, + ), + Text('Song name', style: TextStyle(fontSize: 12.0)) + ]), + Container( + height: 12.0, + ), + ]), + )); + + Widget get actionsToolbar => Container( + width: 100.0, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + _getProfileVideoAction(), + _getVideoAction(title: '3.2m', icon: TikTokIcons.heart), + _getVideoAction(title: '16.4k', icon: TikTokIcons.chat_bubble), + _getVideoAction( + title: 'Share', icon: TikTokIcons.reply, isShare: true), + _getMusicPlayerAction() + ], + ), + ); + + LinearGradient get musicGradient => LinearGradient(colors: [ + Colors.grey[800], + Colors.grey[900], + Colors.grey[900], + Colors.grey[800] + ], stops: [ + 0.0, + 0.4, + 0.6, + 1.0 + ], begin: Alignment.bottomLeft, end: Alignment.topRight); + + Widget _getMusicPlayerAction() { + return Container( + margin: EdgeInsets.only(top: 10.0), + width: ActionWidgetSize, + height: ActionWidgetSize, + child: Column(children: [ + Container( + padding: EdgeInsets.all(11.0), + height: ProfileImageSize, + width: ProfileImageSize, + decoration: BoxDecoration( + gradient: musicGradient, + borderRadius: BorderRadius.circular(ProfileImageSize / 2)), + child: CachedNetworkImage( + imageUrl: + "https://secure.gravatar.com/avatar/ef4a9338dca42372f15427cdb4595ef7", + placeholder: (context, url) => new CircularProgressIndicator(), + errorWidget: (context, url, error) => new Icon(Icons.error), + ), + ), + ])); + } + + Widget get centerSection => Expanded( + child: Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.end, + children: [videoDescription, actionsToolbar])); + + Widget get customCreateIcon => Container( + width: 45.0, + height: 27.0, + child: Stack(children: [ + Container( + margin: EdgeInsets.only(left: 10.0), + width: CreateButtonWidth, + decoration: BoxDecoration( + color: Color.fromARGB(255, 250, 45, 108), + borderRadius: BorderRadius.circular(7.0))), + Container( + margin: EdgeInsets.only(right: 10.0), + width: CreateButtonWidth, + decoration: BoxDecoration( + color: Color.fromARGB(255, 32, 211, 234), + borderRadius: BorderRadius.circular(7.0))), + Center( + child: Container( + height: double.infinity, + width: CreateButtonWidth, + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(7.0)), + child: Icon( + Icons.add, + size: 20.0, + ), + )), + ])); + + Widget get navigationBar => Padding( + padding: EdgeInsets.only(top: 15.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Icon(TikTokIcons.home, color: Colors.white, size: NavigationIconSize), + Icon(TikTokIcons.search, + color: Colors.white, size: NavigationIconSize), + customCreateIcon, + Icon(TikTokIcons.messages, + color: Colors.white, size: NavigationIconSize), + Icon(TikTokIcons.profile, + color: Colors.white, size: NavigationIconSize) + ], + )); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + color: Colors.black, + child: Column( + children: [ + followingContainer, + centerSection, + Opacity( + opacity: 0.1, + child: Container(height: 1.0, color: Colors.grey[300])), + navigationBar, + ], + ), + ), + ); + } + + Widget _getVideoAction({String title, IconData icon, bool isShare = false}) { + return Container( + margin: EdgeInsets.only(top: 15.0), + width: ActionWidgetSize, + height: ActionWidgetSize, + child: Column(children: [ + Icon(icon, + size: isShare ? ShareActionIconSize : ActionIconSize, + color: Colors.grey[300]), + Padding( + padding: EdgeInsets.only(top: isShare ? 5.0 : 2.0), + child: + Text(title, style: TextStyle(fontSize: isShare ? 10.0 : 12.0)), + ) + ])); + } + + Widget _getProfileVideoAction({String pictureUrl}) { + return Stack(children: [ + Container( + margin: EdgeInsets.only(top: 10.0), + width: ActionWidgetSize, + height: ActionWidgetSize, + child: Column(children: [ + Container( + padding: EdgeInsets.all(1.0), + height: ProfileImageSize, + width: ProfileImageSize, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(ProfileImageSize / 2)), + child: CachedNetworkImage( + imageUrl: + "https://secure.gravatar.com/avatar/ef4a9338dca42372f15427cdb4595ef7", + placeholder: (context, url) => new CircularProgressIndicator(), + errorWidget: (context, url, error) => new Icon(Icons.error), + ), + ), + ])), + Positioned( + width: 15.0, + height: 15.0, + bottom: 5, + left: ((ActionWidgetSize / 2) - (15 / 2)), + child: Container( + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(15.0)), + )), + Positioned( + bottom: 0, + left: ((ActionWidgetSize / 2) - (FollowActionIconSize / 2)), + child: Icon(Icons.add_circle, + color: Color.fromARGB(255, 255, 43, 84), + size: FollowActionIconSize)) + ]); + } +} diff --git a/001-tik_tok_ui/final/pubspec.lock b/001-tik_tok_ui/final/pubspec.lock index 374492b3..e1e5b943 100644 --- a/001-tik_tok_ui/final/pubspec.lock +++ b/001-tik_tok_ui/final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,14 +7,14 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" cached_network_image: dependency: "direct main" description: @@ -28,21 +28,14 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" convert: dependency: transitive description: @@ -63,14 +56,7 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -94,7 +80,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.1" + version: "0.12.0+1" http_parser: dependency: transitive description: @@ -108,21 +94,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" path_provider: dependency: transitive description: @@ -136,7 +122,14 @@ packages: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.9.0" + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -148,7 +141,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" sqflite: dependency: transitive description: @@ -169,14 +162,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" synchronized: dependency: transitive description: @@ -197,7 +190,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -220,5 +213,5 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.1.1-dev.0.0 <3.0.0" flutter: ">=1.2.1 <2.0.0" diff --git a/001-tik_tok_ui/final/pubspec.yaml b/001-tik_tok_ui/final/pubspec.yaml index d50cb192..f02bc4f3 100644 --- a/001-tik_tok_ui/final/pubspec.yaml +++ b/001-tik_tok_ui/final/pubspec.yaml @@ -14,7 +14,7 @@ description: A new Flutter project. version: 1.0.0+1 environment: - sdk: ">=2.2.2 <3.0.0" + sdk: ">=2.1.0 <3.0.0" dependencies: flutter: @@ -22,18 +22,20 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 + cupertino_icons: ^0.1.2 cached_network_image: 0.7.0 dev_dependencies: flutter_test: sdk: flutter + # For information on the generic Dart part of this file, see the # following page: https://www.dartlang.org/tools/pub/pubspec # The following section is specific to Flutter. flutter: + # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. @@ -56,9 +58,9 @@ flutter: # list giving the asset and other descriptors for the font. For # example: fonts: - - family: TikTokIcons + - family: TikTokIcons fonts: - - asset: assets/fonts/TikTokIcons.ttf + - asset: assets/fonts/TikTokIcons.ttf # fonts: # - family: Schyler # fonts: diff --git a/001-tik_tok_ui/phase1/.flutter-plugins-dependencies b/001-tik_tok_ui/phase1/.flutter-plugins-dependencies deleted file mode 100644 index 02f7bbf8..00000000 --- a/001-tik_tok_ui/phase1/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-0.5.0+1/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.2/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-0.5.0+1/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.2/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:49:06.052206","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/001-tik_tok_ui/phase1/.gitignore b/001-tik_tok_ui/phase1/.gitignore index 5be59a14..07488ba6 100644 --- a/001-tik_tok_ui/phase1/.gitignore +++ b/001-tik_tok_ui/phase1/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/001-tik_tok_ui/phase1/.metadata b/001-tik_tok_ui/phase1/.metadata index 0012359c..32e51230 100644 --- a/001-tik_tok_ui/phase1/.metadata +++ b/001-tik_tok_ui/phase1/.metadata @@ -1,10 +1,10 @@ -# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app +# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff + channel: master + +project_type: app diff --git a/001-tik_tok_ui/phase1/README.md b/001-tik_tok_ui/phase1/README.md index 4baca98d..365ef92e 100644 --- a/001-tik_tok_ui/phase1/README.md +++ b/001-tik_tok_ui/phase1/README.md @@ -1,3 +1,3 @@ -# Phase 1 - -Empty starting project so you can follow along with the [tutorial on Meduim](https://medium.com/@dane.mackier/breaking-down-tiktoks-ui-using-flutter-8489fe4ad944) +# Phase 1 + +Empty starting project so you can follow along with the [tutorial on Meduim](https://medium.com/@dane.mackier/breaking-down-tiktoks-ui-using-flutter-8489fe4ad944) diff --git a/001-tik_tok_ui/phase1/android/app/build.gradle b/001-tik_tok_ui/phase1/android/app/build.gradle new file mode 100644 index 00000000..97cce324 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.tik_tok_ui" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/001-tik_tok_ui/phase1/android/app/src/debug/AndroidManifest.xml b/001-tik_tok_ui/phase1/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..bea3057d --- /dev/null +++ b/001-tik_tok_ui/phase1/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/001-tik_tok_ui/phase1/android/app/src/main/AndroidManifest.xml b/001-tik_tok_ui/phase1/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..282da854 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase1/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java b/001-tik_tok_ui/phase1/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java new file mode 100644 index 00000000..31def0a5 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.tik_tok_ui; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/001-tik_tok_ui/phase1/android/app/src/main/res/drawable/launch_background.xml b/001-tik_tok_ui/phase1/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/001-tik_tok_ui/phase1/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase1/android/app/src/main/res/values/styles.xml b/001-tik_tok_ui/phase1/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/001-tik_tok_ui/phase1/android/app/src/profile/AndroidManifest.xml b/001-tik_tok_ui/phase1/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..bea3057d --- /dev/null +++ b/001-tik_tok_ui/phase1/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/001-tik_tok_ui/phase1/android/build.gradle b/001-tik_tok_ui/phase1/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/001-tik_tok_ui/phase1/android/gradle.properties b/001-tik_tok_ui/phase1/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/001-tik_tok_ui/phase1/android/gradle/wrapper/gradle-wrapper.properties b/001-tik_tok_ui/phase1/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/001-tik_tok_ui/phase1/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/001-tik_tok_ui/phase1/android/settings.gradle b/001-tik_tok_ui/phase1/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/001-tik_tok_ui/phase1/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/001-tik_tok_ui/phase1/ios/Flutter/AppFrameworkInfo.plist b/001-tik_tok_ui/phase1/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/001-tik_tok_ui/phase1/ios/Flutter/Debug.xcconfig b/001-tik_tok_ui/phase1/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/001-tik_tok_ui/phase1/ios/Flutter/Release.xcconfig b/001-tik_tok_ui/phase1/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/project.pbxproj b/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..3f626825 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase1/ios/Runner.xcworkspace/contents.xcworkspacedata b/001-tik_tok_ui/phase1/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/001-tik_tok_ui/phase1/ios/Runner/AppDelegate.h b/001-tik_tok_ui/phase1/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/001-tik_tok_ui/phase1/ios/Runner/AppDelegate.m b/001-tik_tok_ui/phase1/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/001-tik_tok_ui/phase1/ios/Runner/Base.lproj/LaunchScreen.storyboard b/001-tik_tok_ui/phase1/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase1/ios/Runner/Base.lproj/Main.storyboard b/001-tik_tok_ui/phase1/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase1/ios/Runner/Info.plist b/001-tik_tok_ui/phase1/ios/Runner/Info.plist new file mode 100644 index 00000000..35fbc991 --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + tik_tok_ui + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/001-tik_tok_ui/phase1/ios/Runner/main.m b/001-tik_tok_ui/phase1/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/001-tik_tok_ui/phase1/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/001-tik_tok_ui/phase1/lib/home.dart b/001-tik_tok_ui/phase1/lib/home.dart index 2805f695..87091553 100644 --- a/001-tik_tok_ui/phase1/lib/home.dart +++ b/001-tik_tok_ui/phase1/lib/home.dart @@ -1,13 +1,13 @@ -import 'package:flutter/material.dart'; - -/// Empty page widget fo developers that want to follow along with the tutorial -/// on breaking down and implementing the Tik Tok UI (BLOG_LINK) -class Home extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - ) - ); - } -} +import 'package:flutter/material.dart'; + +/// Empty page widget fo developers that want to follow along with the tutorial +/// on breaking down and implementing the Tik Tok UI (BLOG_LINK) +class Home extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + ) + ); + } +} diff --git a/001-tik_tok_ui/phase1/pubspec.lock b/001-tik_tok_ui/phase1/pubspec.lock index 374492b3..e1e5b943 100644 --- a/001-tik_tok_ui/phase1/pubspec.lock +++ b/001-tik_tok_ui/phase1/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,14 +7,14 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" cached_network_image: dependency: "direct main" description: @@ -28,21 +28,14 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" convert: dependency: transitive description: @@ -63,14 +56,7 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -94,7 +80,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.1" + version: "0.12.0+1" http_parser: dependency: transitive description: @@ -108,21 +94,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" path_provider: dependency: transitive description: @@ -136,7 +122,14 @@ packages: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.9.0" + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -148,7 +141,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" sqflite: dependency: transitive description: @@ -169,14 +162,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" synchronized: dependency: transitive description: @@ -197,7 +190,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -220,5 +213,5 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.1.1-dev.0.0 <3.0.0" flutter: ">=1.2.1 <2.0.0" diff --git a/001-tik_tok_ui/phase1/pubspec.yaml b/001-tik_tok_ui/phase1/pubspec.yaml index 29ccb4f8..f02bc4f3 100644 --- a/001-tik_tok_ui/phase1/pubspec.yaml +++ b/001-tik_tok_ui/phase1/pubspec.yaml @@ -1,75 +1,77 @@ -name: tik_tok_ui -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - cached_network_image: 0.7.0 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: TikTokIcons - fonts: - - asset: assets/fonts/TikTokIcons.ttf - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: tik_tok_ui +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + cached_network_image: 0.7.0 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: TikTokIcons + fonts: + - asset: assets/fonts/TikTokIcons.ttf + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/001-tik_tok_ui/phase1/test/widget_test.dart b/001-tik_tok_ui/phase1/test/widget_test.dart index d2ae893f..a93fc41d 100644 --- a/001-tik_tok_ui/phase1/test/widget_test.dart +++ b/001-tik_tok_ui/phase1/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:tik_tok_ui/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:tik_tok_ui/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/001-tik_tok_ui/phase2/.flutter-plugins-dependencies b/001-tik_tok_ui/phase2/.flutter-plugins-dependencies deleted file mode 100644 index d7610de5..00000000 --- a/001-tik_tok_ui/phase2/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-0.5.0+1/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.2/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-0.5.0+1/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.1.2/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:49:02.967998","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/001-tik_tok_ui/phase2/.gitignore b/001-tik_tok_ui/phase2/.gitignore index 5be59a14..07488ba6 100644 --- a/001-tik_tok_ui/phase2/.gitignore +++ b/001-tik_tok_ui/phase2/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/001-tik_tok_ui/phase2/.metadata b/001-tik_tok_ui/phase2/.metadata index 0012359c..32e51230 100644 --- a/001-tik_tok_ui/phase2/.metadata +++ b/001-tik_tok_ui/phase2/.metadata @@ -1,10 +1,10 @@ -# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app +# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff + channel: master + +project_type: app diff --git a/001-tik_tok_ui/phase2/README.md b/001-tik_tok_ui/phase2/README.md index 4c246220..a66a22a9 100644 --- a/001-tik_tok_ui/phase2/README.md +++ b/001-tik_tok_ui/phase2/README.md @@ -1,3 +1,3 @@ -# Phase 2 - -This is where you end up after you follow the [tutorial on Meduim](https://medium.com/@dane.mackier/breaking-down-tiktoks-ui-using-flutter-8489fe4ad944) +# Phase 2 + +This is where you end up after you follow the [tutorial on Meduim](https://medium.com/@dane.mackier/breaking-down-tiktoks-ui-using-flutter-8489fe4ad944) diff --git a/001-tik_tok_ui/phase2/android/app/build.gradle b/001-tik_tok_ui/phase2/android/app/build.gradle new file mode 100644 index 00000000..97cce324 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.tik_tok_ui" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/001-tik_tok_ui/phase2/android/app/src/debug/AndroidManifest.xml b/001-tik_tok_ui/phase2/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..bea3057d --- /dev/null +++ b/001-tik_tok_ui/phase2/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/001-tik_tok_ui/phase2/android/app/src/main/AndroidManifest.xml b/001-tik_tok_ui/phase2/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..282da854 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase2/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java b/001-tik_tok_ui/phase2/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java new file mode 100644 index 00000000..31def0a5 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/app/src/main/java/com/example/ui_breakdown/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.tik_tok_ui; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/001-tik_tok_ui/phase2/android/app/src/main/res/drawable/launch_background.xml b/001-tik_tok_ui/phase2/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/001-tik_tok_ui/phase2/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/001-tik_tok_ui/phase2/android/app/src/main/res/values/styles.xml b/001-tik_tok_ui/phase2/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/001-tik_tok_ui/phase2/android/app/src/profile/AndroidManifest.xml b/001-tik_tok_ui/phase2/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..bea3057d --- /dev/null +++ b/001-tik_tok_ui/phase2/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/001-tik_tok_ui/phase2/android/build.gradle b/001-tik_tok_ui/phase2/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/001-tik_tok_ui/phase2/android/gradle.properties b/001-tik_tok_ui/phase2/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/001-tik_tok_ui/phase2/android/gradle/wrapper/gradle-wrapper.properties b/001-tik_tok_ui/phase2/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/001-tik_tok_ui/phase2/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/001-tik_tok_ui/phase2/android/settings.gradle b/001-tik_tok_ui/phase2/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/001-tik_tok_ui/phase2/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/001-tik_tok_ui/phase2/ios/Flutter/AppFrameworkInfo.plist b/001-tik_tok_ui/phase2/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/001-tik_tok_ui/phase2/ios/Flutter/Debug.xcconfig b/001-tik_tok_ui/phase2/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/001-tik_tok_ui/phase2/ios/Flutter/Release.xcconfig b/001-tik_tok_ui/phase2/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/project.pbxproj b/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..3f626825 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.uiBreakdown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase2/ios/Runner.xcworkspace/contents.xcworkspacedata b/001-tik_tok_ui/phase2/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/001-tik_tok_ui/phase2/ios/Runner/AppDelegate.h b/001-tik_tok_ui/phase2/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/001-tik_tok_ui/phase2/ios/Runner/AppDelegate.m b/001-tik_tok_ui/phase2/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/001-tik_tok_ui/phase2/ios/Runner/Base.lproj/LaunchScreen.storyboard b/001-tik_tok_ui/phase2/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase2/ios/Runner/Base.lproj/Main.storyboard b/001-tik_tok_ui/phase2/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/001-tik_tok_ui/phase2/ios/Runner/Info.plist b/001-tik_tok_ui/phase2/ios/Runner/Info.plist new file mode 100644 index 00000000..35fbc991 --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + tik_tok_ui + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/001-tik_tok_ui/phase2/ios/Runner/main.m b/001-tik_tok_ui/phase2/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/001-tik_tok_ui/phase2/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/001-tik_tok_ui/phase2/lib/home.dart b/001-tik_tok_ui/phase2/lib/home.dart index 3712976e..de2d0f61 100644 --- a/001-tik_tok_ui/phase2/lib/home.dart +++ b/001-tik_tok_ui/phase2/lib/home.dart @@ -1,34 +1,34 @@ -import 'package:flutter/material.dart'; - -import 'package:tik_tok_ui/widgets/video_description.dart'; -import 'package:tik_tok_ui/widgets/actions_toolbar.dart'; -import 'package:tik_tok_ui/widgets/bottom_toolbar.dart'; - -class Home extends StatelessWidget { - Widget get topSection => Container(height: 100.0, color: Colors.yellow[300]); - - Widget get middleSection => Expanded( - child: Row( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.end, - children: [VideoDescription(), ActionsToolbar()])); - - @override - Widget build(BuildContext context) { - return Scaffold( - drawer: Drawer(child: Container()), - body: Column( - children: [ - // Top section - topSection, - - // Middle expanded - middleSection, - - // Bottom Section - BottomToolbar(), - ], - ), - ); - } -} +import 'package:flutter/material.dart'; + +import 'package:tik_tok_ui/widgets/video_description.dart'; +import 'package:tik_tok_ui/widgets/actions_toolbar.dart'; +import 'package:tik_tok_ui/widgets/bottom_toolbar.dart'; + +class Home extends StatelessWidget { + Widget get topSection => Container(height: 100.0, color: Colors.yellow[300]); + + Widget get middleSection => Expanded( + child: Row( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.end, + children: [VideoDescription(), ActionsToolbar()])); + + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: Drawer(child: Container()), + body: Column( + children: [ + // Top section + topSection, + + // Middle expanded + middleSection, + + // Bottom Section + BottomToolbar(), + ], + ), + ); + } +} diff --git a/001-tik_tok_ui/phase2/lib/widgets/actions_toolbar.dart b/001-tik_tok_ui/phase2/lib/widgets/actions_toolbar.dart index a7e4bb1c..f4d5f568 100644 --- a/001-tik_tok_ui/phase2/lib/widgets/actions_toolbar.dart +++ b/001-tik_tok_ui/phase2/lib/widgets/actions_toolbar.dart @@ -1,20 +1,20 @@ -import 'package:flutter/material.dart'; - -class ActionsToolbar extends StatelessWidget { - - @override - Widget build(BuildContext context) { - return Container( - width: 100.0, - color: Colors.red[300], - child: Column( - mainAxisSize: MainAxisSize.min, - children: List.generate(5, (index) => Container( - width: 60, height: 60, - color: Colors.blue[300], - margin: EdgeInsets.only(top: 20.0))), - ), - ); - } - -} +import 'package:flutter/material.dart'; + +class ActionsToolbar extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return Container( + width: 100.0, + color: Colors.red[300], + child: Column( + mainAxisSize: MainAxisSize.min, + children: List.generate(5, (index) => Container( + width: 60, height: 60, + color: Colors.blue[300], + margin: EdgeInsets.only(top: 20.0))), + ), + ); + } + +} diff --git a/001-tik_tok_ui/phase2/lib/widgets/bottom_toolbar.dart b/001-tik_tok_ui/phase2/lib/widgets/bottom_toolbar.dart index 9b351a48..7f381df9 100644 --- a/001-tik_tok_ui/phase2/lib/widgets/bottom_toolbar.dart +++ b/001-tik_tok_ui/phase2/lib/widgets/bottom_toolbar.dart @@ -1,14 +1,14 @@ -import 'package:flutter/material.dart'; - -class BottomToolbar extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: List.generate( - 5, - (index) => - Container(width: 40.0, height: 40.0, color: Colors.purple[300])), - ); - } -} +import 'package:flutter/material.dart'; + +class BottomToolbar extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: List.generate( + 5, + (index) => + Container(width: 40.0, height: 40.0, color: Colors.purple[300])), + ); + } +} diff --git a/001-tik_tok_ui/phase2/lib/widgets/video_description.dart b/001-tik_tok_ui/phase2/lib/widgets/video_description.dart index 27d67868..6406dd84 100644 --- a/001-tik_tok_ui/phase2/lib/widgets/video_description.dart +++ b/001-tik_tok_ui/phase2/lib/widgets/video_description.dart @@ -1,30 +1,30 @@ -import 'package:flutter/material.dart'; - -class VideoDescription extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Expanded( - child: Container( - height: 70.0, - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: 10.0, - color: Colors.green[300], - margin: EdgeInsets.only(top: 10.0)), - Container( - height: 10.0, - color: Colors.green[300], - margin: EdgeInsets.only(top: 10.0)), - Container( - height: 10.0, - color: Colors.green[300], - margin: EdgeInsets.only(top: 10.0)), - ]) - ) - ); - } -} +import 'package:flutter/material.dart'; + +class VideoDescription extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Expanded( + child: Container( + height: 70.0, + child: Column( + mainAxisSize: MainAxisSize.min, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + height: 10.0, + color: Colors.green[300], + margin: EdgeInsets.only(top: 10.0)), + Container( + height: 10.0, + color: Colors.green[300], + margin: EdgeInsets.only(top: 10.0)), + Container( + height: 10.0, + color: Colors.green[300], + margin: EdgeInsets.only(top: 10.0)), + ]) + ) + ); + } +} diff --git a/001-tik_tok_ui/phase2/pubspec.lock b/001-tik_tok_ui/phase2/pubspec.lock index 374492b3..e1e5b943 100644 --- a/001-tik_tok_ui/phase2/pubspec.lock +++ b/001-tik_tok_ui/phase2/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,14 +7,14 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" cached_network_image: dependency: "direct main" description: @@ -28,21 +28,14 @@ packages: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" convert: dependency: transitive description: @@ -63,14 +56,7 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -94,7 +80,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.12.1" + version: "0.12.0+1" http_parser: dependency: transitive description: @@ -108,21 +94,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" path_provider: dependency: transitive description: @@ -136,7 +122,14 @@ packages: name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.9.0" + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -148,7 +141,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" sqflite: dependency: transitive description: @@ -169,14 +162,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" synchronized: dependency: transitive description: @@ -197,7 +190,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -220,5 +213,5 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.1.1-dev.0.0 <3.0.0" flutter: ">=1.2.1 <2.0.0" diff --git a/001-tik_tok_ui/phase2/pubspec.yaml b/001-tik_tok_ui/phase2/pubspec.yaml index 29ccb4f8..f02bc4f3 100644 --- a/001-tik_tok_ui/phase2/pubspec.yaml +++ b/001-tik_tok_ui/phase2/pubspec.yaml @@ -1,75 +1,77 @@ -name: tik_tok_ui -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - cached_network_image: 0.7.0 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: TikTokIcons - fonts: - - asset: assets/fonts/TikTokIcons.ttf - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: tik_tok_ui +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + cached_network_image: 0.7.0 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: TikTokIcons + fonts: + - asset: assets/fonts/TikTokIcons.ttf + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/001-tik_tok_ui/phase2/test/widget_test.dart b/001-tik_tok_ui/phase2/test/widget_test.dart index d2ae893f..a93fc41d 100644 --- a/001-tik_tok_ui/phase2/test/widget_test.dart +++ b/001-tik_tok_ui/phase2/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:tik_tok_ui/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:tik_tok_ui/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/002-flutter-flare-pt1/01-start/.gitignore b/002-flutter-flare-pt1/01-start/.gitignore index 5be59a14..07488ba6 100644 --- a/002-flutter-flare-pt1/01-start/.gitignore +++ b/002-flutter-flare-pt1/01-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/002-flutter-flare-pt1/01-start/.metadata b/002-flutter-flare-pt1/01-start/.metadata index 0629356e..519f375e 100644 --- a/002-flutter-flare-pt1/01-start/.metadata +++ b/002-flutter-flare-pt1/01-start/.metadata @@ -1,10 +1,10 @@ -# 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: 0067efca61992478336eff172170c4190e1f2137 - channel: master - -project_type: app +# 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: 0067efca61992478336eff172170c4190e1f2137 + channel: master + +project_type: app diff --git a/002-flutter-flare-pt1/01-start/README.md b/002-flutter-flare-pt1/01-start/README.md index d09a71ec..4dd56dd6 100644 --- a/002-flutter-flare-pt1/01-start/README.md +++ b/002-flutter-flare-pt1/01-start/README.md @@ -1,3 +1,3 @@ -# Smarter Flare animation using Flutter - +# Smarter Flare animation using Flutter + This is the starting project for the Tutorial. [Smarter Flare animations with Flutter](https://medium.com/filledstacks/better-animations-in-flutter-using-flare-an-experiment-ddcb35ab0650) \ No newline at end of file diff --git a/002-flutter-flare-pt1/01-start/android/app/build.gradle b/002-flutter-flare-pt1/01-start/android/app/build.gradle new file mode 100644 index 00000000..b8de3c10 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flare_tutorial" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/002-flutter-flare-pt1/01-start/android/app/src/debug/AndroidManifest.xml b/002-flutter-flare-pt1/01-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/AndroidManifest.xml b/002-flutter-flare-pt1/01-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..f70fe9d1 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java b/002-flutter-flare-pt1/01-start/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java new file mode 100644 index 00000000..1ed2c0ce --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flare_tutorial; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/res/drawable/launch_background.xml b/002-flutter-flare-pt1/01-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/002-flutter-flare-pt1/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/01-start/android/app/src/main/res/values/styles.xml b/002-flutter-flare-pt1/01-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/002-flutter-flare-pt1/01-start/android/app/src/profile/AndroidManifest.xml b/002-flutter-flare-pt1/01-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/002-flutter-flare-pt1/01-start/android/build.gradle b/002-flutter-flare-pt1/01-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/002-flutter-flare-pt1/01-start/android/gradle.properties b/002-flutter-flare-pt1/01-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/002-flutter-flare-pt1/01-start/android/gradle/wrapper/gradle-wrapper.properties b/002-flutter-flare-pt1/01-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/002-flutter-flare-pt1/01-start/android/settings.gradle b/002-flutter-flare-pt1/01-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/002-flutter-flare-pt1/01-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/002-flutter-flare-pt1/01-start/ios/Flutter/AppFrameworkInfo.plist b/002-flutter-flare-pt1/01-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/002-flutter-flare-pt1/01-start/ios/Flutter/Debug.xcconfig b/002-flutter-flare-pt1/01-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/002-flutter-flare-pt1/01-start/ios/Flutter/Release.xcconfig b/002-flutter-flare-pt1/01-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/project.pbxproj b/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..54679793 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/002-flutter-flare-pt1/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/AppDelegate.h b/002-flutter-flare-pt1/01-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/AppDelegate.m b/002-flutter-flare-pt1/01-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/002-flutter-flare-pt1/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Base.lproj/Main.storyboard b/002-flutter-flare-pt1/01-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/Info.plist b/002-flutter-flare-pt1/01-start/ios/Runner/Info.plist new file mode 100644 index 00000000..33f64a5b --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flare_tutorial + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/002-flutter-flare-pt1/01-start/ios/Runner/main.m b/002-flutter-flare-pt1/01-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/002-flutter-flare-pt1/01-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/002-flutter-flare-pt1/01-start/lib/flare_demo.dart b/002-flutter-flare-pt1/01-start/lib/flare_demo.dart index a39ee98d..9b7a49c7 100644 --- a/002-flutter-flare-pt1/01-start/lib/flare_demo.dart +++ b/002-flutter-flare-pt1/01-start/lib/flare_demo.dart @@ -1,16 +1,16 @@ -import 'package:flutter/material.dart'; - -class FlareDemo extends StatefulWidget { - @override - _FlareDemoState createState() => _FlareDemoState(); -} - -class _FlareDemoState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Color.fromARGB(255, 102, 18, 222), - body: Center(child: Text('Flare Demo')), - ); - } -} +import 'package:flutter/material.dart'; + +class FlareDemo extends StatefulWidget { + @override + _FlareDemoState createState() => _FlareDemoState(); +} + +class _FlareDemoState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromARGB(255, 102, 18, 222), + body: Center(child: Text('Flare Demo')), + ); + } +} diff --git a/002-flutter-flare-pt1/01-start/lib/main.dart b/002-flutter-flare-pt1/01-start/lib/main.dart index 4dfe1d19..f9207aad 100644 --- a/002-flutter-flare-pt1/01-start/lib/main.dart +++ b/002-flutter-flare-pt1/01-start/lib/main.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; -import 'package:flare_tutorial/flare_demo.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: FlareDemo()); - } -} +import 'package:flutter/material.dart'; +import 'package:flare_tutorial/flare_demo.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: FlareDemo()); + } +} diff --git a/002-flutter-flare-pt1/01-start/pubspec.lock b/002-flutter-flare-pt1/01-start/pubspec.lock index 066a096b..e6c59b03 100644 --- a/002-flutter-flare-pt1/01-start/pubspec.lock +++ b/002-flutter-flare-pt1/01-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -106,14 +106,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/002-flutter-flare-pt1/01-start/pubspec.yaml b/002-flutter-flare-pt1/01-start/pubspec.yaml index 8822af5b..b0c1fc87 100644 --- a/002-flutter-flare-pt1/01-start/pubspec.yaml +++ b/002-flutter-flare-pt1/01-start/pubspec.yaml @@ -1,66 +1,66 @@ -name: flare_tutorial -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_ham.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flare_tutorial +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_ham.jpeg + # - images/a_dot_ham.jpeg + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/002-flutter-flare-pt1/01-start/test/widget_test.dart b/002-flutter-flare-pt1/01-start/test/widget_test.dart index e9c2fb3b..94038d0a 100644 --- a/002-flutter-flare-pt1/01-start/test/widget_test.dart +++ b/002-flutter-flare-pt1/01-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flare_tutorial/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flare_tutorial/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/002-flutter-flare-pt1/02-open-close/.gitignore b/002-flutter-flare-pt1/02-open-close/.gitignore index 5be59a14..07488ba6 100644 --- a/002-flutter-flare-pt1/02-open-close/.gitignore +++ b/002-flutter-flare-pt1/02-open-close/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/002-flutter-flare-pt1/02-open-close/.metadata b/002-flutter-flare-pt1/02-open-close/.metadata index 0629356e..519f375e 100644 --- a/002-flutter-flare-pt1/02-open-close/.metadata +++ b/002-flutter-flare-pt1/02-open-close/.metadata @@ -1,10 +1,10 @@ -# 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: 0067efca61992478336eff172170c4190e1f2137 - channel: master - -project_type: app +# 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: 0067efca61992478336eff172170c4190e1f2137 + channel: master + +project_type: app diff --git a/002-flutter-flare-pt1/02-open-close/README.md b/002-flutter-flare-pt1/02-open-close/README.md index 375f54fe..275d7696 100644 --- a/002-flutter-flare-pt1/02-open-close/README.md +++ b/002-flutter-flare-pt1/02-open-close/README.md @@ -1,3 +1,3 @@ -# Smarter Flare animation using Flutter - +# Smarter Flare animation using Flutter + This is the first stop in the tutorial. [Smarter Flare animations with Flutter](https://medium.com/filledstacks/better-animations-in-flutter-using-flare-an-experiment-ddcb35ab0650) \ No newline at end of file diff --git a/002-flutter-flare-pt1/02-open-close/android/app/build.gradle b/002-flutter-flare-pt1/02-open-close/android/app/build.gradle new file mode 100644 index 00000000..b8de3c10 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flare_tutorial" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/debug/AndroidManifest.xml b/002-flutter-flare-pt1/02-open-close/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/AndroidManifest.xml b/002-flutter-flare-pt1/02-open-close/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..f70fe9d1 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java b/002-flutter-flare-pt1/02-open-close/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java new file mode 100644 index 00000000..1ed2c0ce --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flare_tutorial; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/drawable/launch_background.xml b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/values/styles.xml b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/002-flutter-flare-pt1/02-open-close/android/app/src/profile/AndroidManifest.xml b/002-flutter-flare-pt1/02-open-close/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/002-flutter-flare-pt1/02-open-close/android/build.gradle b/002-flutter-flare-pt1/02-open-close/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/002-flutter-flare-pt1/02-open-close/android/gradle.properties b/002-flutter-flare-pt1/02-open-close/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/002-flutter-flare-pt1/02-open-close/android/gradle/wrapper/gradle-wrapper.properties b/002-flutter-flare-pt1/02-open-close/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/002-flutter-flare-pt1/02-open-close/android/settings.gradle b/002-flutter-flare-pt1/02-open-close/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/002-flutter-flare-pt1/02-open-close/ios/Flutter/AppFrameworkInfo.plist b/002-flutter-flare-pt1/02-open-close/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/002-flutter-flare-pt1/02-open-close/ios/Flutter/Debug.xcconfig b/002-flutter-flare-pt1/02-open-close/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/002-flutter-flare-pt1/02-open-close/ios/Flutter/Release.xcconfig b/002-flutter-flare-pt1/02-open-close/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/project.pbxproj b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..54679793 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner.xcworkspace/contents.xcworkspacedata b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/AppDelegate.h b/002-flutter-flare-pt1/02-open-close/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/AppDelegate.m b/002-flutter-flare-pt1/02-open-close/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Base.lproj/LaunchScreen.storyboard b/002-flutter-flare-pt1/02-open-close/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Base.lproj/Main.storyboard b/002-flutter-flare-pt1/02-open-close/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/Info.plist b/002-flutter-flare-pt1/02-open-close/ios/Runner/Info.plist new file mode 100644 index 00000000..33f64a5b --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flare_tutorial + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/002-flutter-flare-pt1/02-open-close/ios/Runner/main.m b/002-flutter-flare-pt1/02-open-close/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/002-flutter-flare-pt1/02-open-close/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/002-flutter-flare-pt1/02-open-close/lib/flare_demo.dart b/002-flutter-flare-pt1/02-open-close/lib/flare_demo.dart index 3f5b99f2..5e80c98f 100644 --- a/002-flutter-flare-pt1/02-open-close/lib/flare_demo.dart +++ b/002-flutter-flare-pt1/02-open-close/lib/flare_demo.dart @@ -1,25 +1,25 @@ -import 'package:flutter/material.dart'; -import 'package:flare_flutter/flare_actor.dart'; - -class FlareDemo extends StatefulWidget { - @override - _FlareDemoState createState() => _FlareDemoState(); -} - -class _FlareDemoState extends State { - bool isOpen = false; - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Color.fromARGB(255, 102, 18, 222), - body: GestureDetector( - onTap: () { - setState(() { - isOpen = !isOpen; - }); - }, - child: FlareActor('assets/button-animation.flr', - animation: isOpen ? 'activate' : 'deactivate'))); - } -} +import 'package:flutter/material.dart'; +import 'package:flare_flutter/flare_actor.dart'; + +class FlareDemo extends StatefulWidget { + @override + _FlareDemoState createState() => _FlareDemoState(); +} + +class _FlareDemoState extends State { + bool isOpen = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromARGB(255, 102, 18, 222), + body: GestureDetector( + onTap: () { + setState(() { + isOpen = !isOpen; + }); + }, + child: FlareActor('assets/button-animation.flr', + animation: isOpen ? 'activate' : 'deactivate'))); + } +} diff --git a/002-flutter-flare-pt1/02-open-close/lib/main.dart b/002-flutter-flare-pt1/02-open-close/lib/main.dart index 4dfe1d19..f9207aad 100644 --- a/002-flutter-flare-pt1/02-open-close/lib/main.dart +++ b/002-flutter-flare-pt1/02-open-close/lib/main.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; -import 'package:flare_tutorial/flare_demo.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: FlareDemo()); - } -} +import 'package:flutter/material.dart'; +import 'package:flare_tutorial/flare_demo.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: FlareDemo()); + } +} diff --git a/002-flutter-flare-pt1/02-open-close/pubspec.lock b/002-flutter-flare-pt1/02-open-close/pubspec.lock index caa11c3c..57c200bb 100644 --- a/002-flutter-flare-pt1/02-open-close/pubspec.lock +++ b/002-flutter-flare-pt1/02-open-close/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flare_dart: dependency: transitive description: @@ -80,21 +66,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -106,7 +106,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -120,14 +120,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -157,4 +157,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/002-flutter-flare-pt1/02-open-close/pubspec.yaml b/002-flutter-flare-pt1/02-open-close/pubspec.yaml index f0d18df1..cbbceaf5 100644 --- a/002-flutter-flare-pt1/02-open-close/pubspec.yaml +++ b/002-flutter-flare-pt1/02-open-close/pubspec.yaml @@ -1,67 +1,67 @@ -name: flare_tutorial -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - flare_flutter: any - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - assets: - - button-animation.flr - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flare_tutorial +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + flare_flutter: any + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + # To add assets to your application, add an assets section, like this: + assets: + - button-animation.flr + # - images/a_dot_ham.jpeg + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/002-flutter-flare-pt1/02-open-close/test/widget_test.dart b/002-flutter-flare-pt1/02-open-close/test/widget_test.dart index e9c2fb3b..94038d0a 100644 --- a/002-flutter-flare-pt1/02-open-close/test/widget_test.dart +++ b/002-flutter-flare-pt1/02-open-close/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flare_tutorial/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flare_tutorial/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/.gitignore b/002-flutter-flare-pt1/03-multiple-areas/.gitignore index 5be59a14..07488ba6 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/.gitignore +++ b/002-flutter-flare-pt1/03-multiple-areas/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/002-flutter-flare-pt1/03-multiple-areas/.metadata b/002-flutter-flare-pt1/03-multiple-areas/.metadata index 0629356e..519f375e 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/.metadata +++ b/002-flutter-flare-pt1/03-multiple-areas/.metadata @@ -1,10 +1,10 @@ -# 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: 0067efca61992478336eff172170c4190e1f2137 - channel: master - -project_type: app +# 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: 0067efca61992478336eff172170c4190e1f2137 + channel: master + +project_type: app diff --git a/002-flutter-flare-pt1/03-multiple-areas/README.md b/002-flutter-flare-pt1/03-multiple-areas/README.md index 97c12ceb..46b7448b 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/README.md +++ b/002-flutter-flare-pt1/03-multiple-areas/README.md @@ -1,3 +1,3 @@ -# Smarter Flare animation using Flutter - Final - +# Smarter Flare animation using Flutter - Final + This is the final result for the tutorial. [Smarter Flare animations with Flutter](https://medium.com/filledstacks/better-animations-in-flutter-using-flare-an-experiment-ddcb35ab0650) \ No newline at end of file diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/build.gradle b/002-flutter-flare-pt1/03-multiple-areas/android/app/build.gradle new file mode 100644 index 00000000..b8de3c10 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flare_tutorial" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/debug/AndroidManifest.xml b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/AndroidManifest.xml b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..f70fe9d1 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java new file mode 100644 index 00000000..1ed2c0ce --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flare_tutorial; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/drawable/launch_background.xml b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/values/styles.xml b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/app/src/profile/AndroidManifest.xml b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/build.gradle b/002-flutter-flare-pt1/03-multiple-areas/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/gradle.properties b/002-flutter-flare-pt1/03-multiple-areas/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/gradle/wrapper/gradle-wrapper.properties b/002-flutter-flare-pt1/03-multiple-areas/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/002-flutter-flare-pt1/03-multiple-areas/android/settings.gradle b/002-flutter-flare-pt1/03-multiple-areas/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/AppFrameworkInfo.plist b/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/Debug.xcconfig b/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/Release.xcconfig b/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/project.pbxproj b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..54679793 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcworkspace/contents.xcworkspacedata b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/AppDelegate.h b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/AppDelegate.m b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Base.lproj/LaunchScreen.storyboard b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Base.lproj/Main.storyboard b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Info.plist b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Info.plist new file mode 100644 index 00000000..33f64a5b --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flare_tutorial + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/main.m b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/002-flutter-flare-pt1/03-multiple-areas/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/lib/flare_demo.dart b/002-flutter-flare-pt1/03-multiple-areas/lib/flare_demo.dart index 2dd02ca7..a9b21696 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/lib/flare_demo.dart +++ b/002-flutter-flare-pt1/03-multiple-areas/lib/flare_demo.dart @@ -1,18 +1,18 @@ -import 'package:flutter/material.dart'; -import 'package:flare_tutorial/smart_flare_animation.dart'; - -class FlareDemo extends StatefulWidget { - @override - _FlareDemoState createState() => _FlareDemoState(); -} - -class _FlareDemoState extends State { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Color.fromARGB(255, 102, 18, 222), - body: Align( - alignment: Alignment.bottomCenter, - child: SmartFlareAnimation())); - } -} +import 'package:flutter/material.dart'; +import 'package:flare_tutorial/smart_flare_animation.dart'; + +class FlareDemo extends StatefulWidget { + @override + _FlareDemoState createState() => _FlareDemoState(); +} + +class _FlareDemoState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color.fromARGB(255, 102, 18, 222), + body: Align( + alignment: Alignment.bottomCenter, + child: SmartFlareAnimation())); + } +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/lib/main.dart b/002-flutter-flare-pt1/03-multiple-areas/lib/main.dart index 4dfe1d19..f9207aad 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/lib/main.dart +++ b/002-flutter-flare-pt1/03-multiple-areas/lib/main.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; -import 'package:flare_tutorial/flare_demo.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: FlareDemo()); - } -} +import 'package:flutter/material.dart'; +import 'package:flare_tutorial/flare_demo.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: FlareDemo()); + } +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/lib/smart_flare_animation.dart b/002-flutter-flare-pt1/03-multiple-areas/lib/smart_flare_animation.dart index fa474b3c..6e70485e 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/lib/smart_flare_animation.dart +++ b/002-flutter-flare-pt1/03-multiple-areas/lib/smart_flare_animation.dart @@ -1,98 +1,101 @@ -import 'package:flutter/material.dart'; -import 'package:flare_flutter/flare_actor.dart'; -import 'package:flare_flutter/flare_controls.dart'; - -enum AnimationToPlay { - Activate, - Deactivate, - CameraTapped, - PulseTapped, - ImageTapped -} - -class SmartFlareAnimation extends StatefulWidget { - _SmartFlareAnimationState createState() => _SmartFlareAnimationState(); -} - -class _SmartFlareAnimationState extends State { - // width and height retrieved from the artboard values in the animation - static const double AnimationWidth = 295.0; - static const double AnimationHeight = 251.0; - - AnimationToPlay _lastPlayedAnimation; - - // Flare animation controls - final FlareControls animationControls = FlareControls(); - - bool isOpen = false; - - @override - Widget build(BuildContext context) { - return Container( - width: AnimationWidth, - height: AnimationHeight, - child: GestureDetector( - onTapUp: (tapInfo) { - var localTouchPosition = (context.findRenderObject() as RenderBox) - .globalToLocal(tapInfo.globalPosition); - - var topHalfTouched = localTouchPosition.dy < AnimationHeight / 2; - - var leftSideTouched = localTouchPosition.dx < AnimationWidth / 3; - - var rightSideTouched = - localTouchPosition.dx > (AnimationWidth / 3) * 2; - - var middleTouched = !leftSideTouched && !rightSideTouched; - - // Call our animation in our conditional checks - if (leftSideTouched && topHalfTouched) { - _setAnimationToPlay(AnimationToPlay.CameraTapped); - } else if (middleTouched && topHalfTouched) { - _setAnimationToPlay(AnimationToPlay.PulseTapped); - } else if (rightSideTouched && topHalfTouched) { - _setAnimationToPlay(AnimationToPlay.ImageTapped); - } else { - if (isOpen) { - _setAnimationToPlay(AnimationToPlay.Deactivate); - } else { - _setAnimationToPlay(AnimationToPlay.Activate); - } - - isOpen = !isOpen; - } - }, - child: FlareActor('assets/button-animation.flr', - controller: animationControls, animation: 'deactivate')), - ); - } - - String _getAnimationName(AnimationToPlay animationToPlay) { - switch (animationToPlay) { - case AnimationToPlay.Activate: - return 'activate'; - case AnimationToPlay.Deactivate: - return 'deactivate'; - case AnimationToPlay.CameraTapped: - return 'camera_tapped'; - case AnimationToPlay.PulseTapped: - return 'pulse_tapped'; - case AnimationToPlay.ImageTapped: - return 'image_tapped'; - default: - return 'deactivate'; - } - } - - void _setAnimationToPlay(AnimationToPlay animation) { - var isTappedAnimation = _getAnimationName(animation).contains("_tapped"); - if (isTappedAnimation && - _lastPlayedAnimation == AnimationToPlay.Deactivate) { - return; - } - - animationControls.play(_getAnimationName(animation)); - - _lastPlayedAnimation = animation; - } -} +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flare_flutter/flare_actor.dart'; +import 'package:flare_flutter/flare_controls.dart'; + +enum AnimationToPlay { + Activate, + Deactivate, + CameraTapped, + PulseTapped, + ImageTapped +} + +class SmartFlareAnimation extends StatefulWidget { + _SmartFlareAnimationState createState() => _SmartFlareAnimationState(); +} + +class _SmartFlareAnimationState extends State { + // width and height retrieved from the artboard values in the animation + static const double AnimationWidth = 295.0; + static const double AnimationHeight = 251.0; + + AnimationToPlay _animationToPlay = AnimationToPlay.Deactivate; + AnimationToPlay _lastPlayedAnimation; + + // Flare animation controls + final FlareControls animationControls = FlareControls(); + + bool isOpen = false; + + @override + Widget build(BuildContext context) { + return Container( + width: AnimationWidth, + height: AnimationHeight, + child: GestureDetector( + onTapUp: (tapInfo) { + var localTouchPosition = (context.findRenderObject() as RenderBox) + .globalToLocal(tapInfo.globalPosition); + + var topHalfTouched = localTouchPosition.dy < AnimationHeight / 2; + + var leftSideTouched = localTouchPosition.dx < AnimationWidth / 3; + + var rightSideTouched = + localTouchPosition.dx > (AnimationWidth / 3) * 2; + + var middleTouched = !leftSideTouched && !rightSideTouched; + + // Call our animation in our conditional checks + if (leftSideTouched && topHalfTouched) { + _setAnimationToPlay(AnimationToPlay.CameraTapped); + } else if (middleTouched && topHalfTouched) { + _setAnimationToPlay(AnimationToPlay.PulseTapped); + } else if (rightSideTouched && topHalfTouched) { + _setAnimationToPlay(AnimationToPlay.ImageTapped); + } else { + if (isOpen) { + _setAnimationToPlay(AnimationToPlay.Deactivate); + } else { + _setAnimationToPlay(AnimationToPlay.Activate); + } + + isOpen = !isOpen; + } + }, + child: FlareActor('assets/button-animation.flr', + controller: animationControls, animation: 'deactivate')), + ); + } + + String _getAnimationName(AnimationToPlay animationToPlay) { + switch (animationToPlay) { + case AnimationToPlay.Activate: + return 'activate'; + case AnimationToPlay.Deactivate: + return 'deactivate'; + case AnimationToPlay.CameraTapped: + return 'camera_tapped'; + case AnimationToPlay.PulseTapped: + return 'pulse_tapped'; + case AnimationToPlay.ImageTapped: + return 'image_tapped'; + default: + return 'deactivate'; + } + } + + void _setAnimationToPlay(AnimationToPlay animation) { + var isTappedAnimation = _getAnimationName(animation).contains("_tapped"); + if (isTappedAnimation && + _lastPlayedAnimation == AnimationToPlay.Deactivate) { + return; + } + + animationControls.play(_getAnimationName(animation)); + + _lastPlayedAnimation = animation; + } +} diff --git a/002-flutter-flare-pt1/03-multiple-areas/pubspec.lock b/002-flutter-flare-pt1/03-multiple-areas/pubspec.lock index caa11c3c..57c200bb 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/pubspec.lock +++ b/002-flutter-flare-pt1/03-multiple-areas/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flare_dart: dependency: transitive description: @@ -80,21 +66,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -106,7 +106,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -120,14 +120,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -157,4 +157,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/002-flutter-flare-pt1/03-multiple-areas/pubspec.yaml b/002-flutter-flare-pt1/03-multiple-areas/pubspec.yaml index f0d18df1..cbbceaf5 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/pubspec.yaml +++ b/002-flutter-flare-pt1/03-multiple-areas/pubspec.yaml @@ -1,67 +1,67 @@ -name: flare_tutorial -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - flare_flutter: any - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - assets: - - button-animation.flr - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flare_tutorial +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + flare_flutter: any + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + # To add assets to your application, add an assets section, like this: + assets: + - button-animation.flr + # - images/a_dot_ham.jpeg + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/002-flutter-flare-pt1/03-multiple-areas/test/widget_test.dart b/002-flutter-flare-pt1/03-multiple-areas/test/widget_test.dart index e9c2fb3b..94038d0a 100644 --- a/002-flutter-flare-pt1/03-multiple-areas/test/widget_test.dart +++ b/002-flutter-flare-pt1/03-multiple-areas/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flare_tutorial/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flare_tutorial/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/003-smart-flare/01-start/.gitignore b/003-smart-flare/01-start/.gitignore index 5be59a14..07488ba6 100644 --- a/003-smart-flare/01-start/.gitignore +++ b/003-smart-flare/01-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/003-smart-flare/01-start/.metadata b/003-smart-flare/01-start/.metadata index 0629356e..519f375e 100644 --- a/003-smart-flare/01-start/.metadata +++ b/003-smart-flare/01-start/.metadata @@ -1,10 +1,10 @@ -# 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: 0067efca61992478336eff172170c4190e1f2137 - channel: master - -project_type: app +# 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: 0067efca61992478336eff172170c4190e1f2137 + channel: master + +project_type: app diff --git a/003-smart-flare/01-start/README.md b/003-smart-flare/01-start/README.md index 37889c66..a54c12c8 100644 --- a/003-smart-flare/01-start/README.md +++ b/003-smart-flare/01-start/README.md @@ -1,3 +1,3 @@ -# Smarter Flare - tutorias - +# Smarter Flare - tutorias + This is the starting project for the smart-flare tutorial. [Using SmartFlare and Flare](https://medium.com/@dane.mackier/smartflare-for-interactive-flareactors-an-experiment-and-package-e5bcfe652503) \ No newline at end of file diff --git a/003-smart-flare/01-start/android/app/build.gradle b/003-smart-flare/01-start/android/app/build.gradle new file mode 100644 index 00000000..b8de3c10 --- /dev/null +++ b/003-smart-flare/01-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flare_tutorial" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/003-smart-flare/01-start/android/app/src/debug/AndroidManifest.xml b/003-smart-flare/01-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/003-smart-flare/01-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/003-smart-flare/01-start/android/app/src/main/AndroidManifest.xml b/003-smart-flare/01-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..f70fe9d1 --- /dev/null +++ b/003-smart-flare/01-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/003-smart-flare/01-start/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java b/003-smart-flare/01-start/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java new file mode 100644 index 00000000..1ed2c0ce --- /dev/null +++ b/003-smart-flare/01-start/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flare_tutorial; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/003-smart-flare/01-start/android/app/src/main/res/drawable/launch_background.xml b/003-smart-flare/01-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/003-smart-flare/01-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/003-smart-flare/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/003-smart-flare/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/003-smart-flare/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/003-smart-flare/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/003-smart-flare/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/003-smart-flare/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/003-smart-flare/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/003-smart-flare/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/003-smart-flare/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/003-smart-flare/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/003-smart-flare/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/003-smart-flare/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/003-smart-flare/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/003-smart-flare/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/003-smart-flare/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/003-smart-flare/01-start/android/app/src/main/res/values/styles.xml b/003-smart-flare/01-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/003-smart-flare/01-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/003-smart-flare/01-start/android/app/src/profile/AndroidManifest.xml b/003-smart-flare/01-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/003-smart-flare/01-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/003-smart-flare/01-start/android/build.gradle b/003-smart-flare/01-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/003-smart-flare/01-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/003-smart-flare/01-start/android/gradle.properties b/003-smart-flare/01-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/003-smart-flare/01-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/003-smart-flare/01-start/android/gradle/wrapper/gradle-wrapper.properties b/003-smart-flare/01-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/003-smart-flare/01-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/003-smart-flare/01-start/android/settings.gradle b/003-smart-flare/01-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/003-smart-flare/01-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/003-smart-flare/01-start/ios/Flutter/AppFrameworkInfo.plist b/003-smart-flare/01-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/003-smart-flare/01-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/003-smart-flare/01-start/ios/Flutter/Debug.xcconfig b/003-smart-flare/01-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/003-smart-flare/01-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/003-smart-flare/01-start/ios/Flutter/Release.xcconfig b/003-smart-flare/01-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/003-smart-flare/01-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/003-smart-flare/01-start/ios/Runner.xcodeproj/project.pbxproj b/003-smart-flare/01-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..54679793 --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/003-smart-flare/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/003-smart-flare/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/003-smart-flare/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/003-smart-flare/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/003-smart-flare/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/003-smart-flare/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/003-smart-flare/01-start/ios/Runner/AppDelegate.h b/003-smart-flare/01-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/003-smart-flare/01-start/ios/Runner/AppDelegate.m b/003-smart-flare/01-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/003-smart-flare/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/003-smart-flare/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/003-smart-flare/01-start/ios/Runner/Base.lproj/Main.storyboard b/003-smart-flare/01-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/003-smart-flare/01-start/ios/Runner/Info.plist b/003-smart-flare/01-start/ios/Runner/Info.plist new file mode 100644 index 00000000..33f64a5b --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flare_tutorial + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/003-smart-flare/01-start/ios/Runner/main.m b/003-smart-flare/01-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/003-smart-flare/01-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/003-smart-flare/01-start/lib/flare_demo.dart b/003-smart-flare/01-start/lib/flare_demo.dart index 9445c75f..6ba4099a 100644 --- a/003-smart-flare/01-start/lib/flare_demo.dart +++ b/003-smart-flare/01-start/lib/flare_demo.dart @@ -1,25 +1,25 @@ -import 'package:flutter/material.dart'; -import 'package:smart_flare/smart_flare.dart'; - -class FlareDemo extends StatefulWidget { - @override - _FlareDemoState createState() => _FlareDemoState(); -} - -class _FlareDemoState extends State { - @override - Widget build(BuildContext context) { - var animationWidth = 295.0; - var animationHeight = 251.0; - return Scaffold( - backgroundColor: Color.fromARGB(255, 102, 18, 222), - body: Align( - alignment: Alignment.bottomCenter, - child: SmartFlareActor( - width: animationWidth, - height: animationHeight, - filename: 'assets/button-animation.flr', - startingAnimation: 'deactivate', - ))); - } -} +import 'package:flutter/material.dart'; +import 'package:smart_flare/smart_flare.dart'; + +class FlareDemo extends StatefulWidget { + @override + _FlareDemoState createState() => _FlareDemoState(); +} + +class _FlareDemoState extends State { + @override + Widget build(BuildContext context) { + var animationWidth = 295.0; + var animationHeight = 251.0; + return Scaffold( + backgroundColor: Color.fromARGB(255, 102, 18, 222), + body: Align( + alignment: Alignment.bottomCenter, + child: SmartFlareActor( + width: animationWidth, + height: animationHeight, + filename: 'assets/button-animation.flr', + startingAnimation: 'deactivate', + ))); + } +} diff --git a/003-smart-flare/01-start/lib/main.dart b/003-smart-flare/01-start/lib/main.dart index 0ff78fdc..425f74b5 100644 --- a/003-smart-flare/01-start/lib/main.dart +++ b/003-smart-flare/01-start/lib/main.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; -import 'flare_demo.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: FlareDemo()); - } -} +import 'package:flutter/material.dart'; +import 'flare_demo.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: FlareDemo()); + } +} diff --git a/003-smart-flare/01-start/pubspec.lock b/003-smart-flare/01-start/pubspec.lock index cbbc209f..c363c06e 100644 --- a/003-smart-flare/01-start/pubspec.lock +++ b/003-smart-flare/01-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flare_dart: dependency: transitive description: @@ -80,21 +66,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -113,7 +113,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -127,14 +127,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -148,7 +148,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -164,4 +164,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/003-smart-flare/01-start/pubspec.yaml b/003-smart-flare/01-start/pubspec.yaml index 9e20101c..624d6280 100644 --- a/003-smart-flare/01-start/pubspec.yaml +++ b/003-smart-flare/01-start/pubspec.yaml @@ -1,68 +1,68 @@ -name: flare_tutorial -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - flare_flutter: any - smart_flare: any - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - assets: - - button-animation.flr - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flare_tutorial +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + flare_flutter: any + smart_flare: any + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + # To add assets to your application, add an assets section, like this: + assets: + - button-animation.flr + # - images/a_dot_ham.jpeg + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/003-smart-flare/02-final/.gitignore b/003-smart-flare/02-final/.gitignore index 5be59a14..07488ba6 100644 --- a/003-smart-flare/02-final/.gitignore +++ b/003-smart-flare/02-final/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/003-smart-flare/02-final/.metadata b/003-smart-flare/02-final/.metadata index 0629356e..519f375e 100644 --- a/003-smart-flare/02-final/.metadata +++ b/003-smart-flare/02-final/.metadata @@ -1,10 +1,10 @@ -# 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: 0067efca61992478336eff172170c4190e1f2137 - channel: master - -project_type: app +# 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: 0067efca61992478336eff172170c4190e1f2137 + channel: master + +project_type: app diff --git a/003-smart-flare/02-final/README.md b/003-smart-flare/02-final/README.md index 19dc5005..16563965 100644 --- a/003-smart-flare/02-final/README.md +++ b/003-smart-flare/02-final/README.md @@ -1,3 +1,3 @@ -# Smarter Flare - tutorias - +# Smarter Flare - tutorias + This is the final project for the smart-flare tutorial.\[ [Youtube Video](https://youtu.be/vsyjMrZa5OU) \] [Using SmartFlare and Flare](https://medium.com/@dane.mackier/smartflare-for-interactive-flareactors-an-experiment-and-package-e5bcfe652503) \ No newline at end of file diff --git a/003-smart-flare/02-final/android/app/build.gradle b/003-smart-flare/02-final/android/app/build.gradle new file mode 100644 index 00000000..b8de3c10 --- /dev/null +++ b/003-smart-flare/02-final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flare_tutorial" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/003-smart-flare/02-final/android/app/src/debug/AndroidManifest.xml b/003-smart-flare/02-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/003-smart-flare/02-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/003-smart-flare/02-final/android/app/src/main/AndroidManifest.xml b/003-smart-flare/02-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..f70fe9d1 --- /dev/null +++ b/003-smart-flare/02-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/003-smart-flare/02-final/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java b/003-smart-flare/02-final/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java new file mode 100644 index 00000000..1ed2c0ce --- /dev/null +++ b/003-smart-flare/02-final/android/app/src/main/java/com/example/flare_tutorial/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flare_tutorial; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/003-smart-flare/02-final/android/app/src/main/res/drawable/launch_background.xml b/003-smart-flare/02-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/003-smart-flare/02-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/003-smart-flare/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/003-smart-flare/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/003-smart-flare/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/003-smart-flare/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/003-smart-flare/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/003-smart-flare/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/003-smart-flare/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/003-smart-flare/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/003-smart-flare/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/003-smart-flare/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/003-smart-flare/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/003-smart-flare/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/003-smart-flare/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/003-smart-flare/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/003-smart-flare/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/003-smart-flare/02-final/android/app/src/main/res/values/styles.xml b/003-smart-flare/02-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/003-smart-flare/02-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/003-smart-flare/02-final/android/app/src/profile/AndroidManifest.xml b/003-smart-flare/02-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..cd2376cf --- /dev/null +++ b/003-smart-flare/02-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/003-smart-flare/02-final/android/build.gradle b/003-smart-flare/02-final/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/003-smart-flare/02-final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/003-smart-flare/02-final/android/gradle.properties b/003-smart-flare/02-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/003-smart-flare/02-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/003-smart-flare/02-final/android/gradle/wrapper/gradle-wrapper.properties b/003-smart-flare/02-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/003-smart-flare/02-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/003-smart-flare/02-final/android/settings.gradle b/003-smart-flare/02-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/003-smart-flare/02-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/003-smart-flare/02-final/ios/Flutter/AppFrameworkInfo.plist b/003-smart-flare/02-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/003-smart-flare/02-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/003-smart-flare/02-final/ios/Flutter/Debug.xcconfig b/003-smart-flare/02-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/003-smart-flare/02-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/003-smart-flare/02-final/ios/Flutter/Release.xcconfig b/003-smart-flare/02-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/003-smart-flare/02-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/003-smart-flare/02-final/ios/Runner.xcodeproj/project.pbxproj b/003-smart-flare/02-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..54679793 --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareTutorial; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/003-smart-flare/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/003-smart-flare/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/003-smart-flare/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/003-smart-flare/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/003-smart-flare/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/003-smart-flare/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/003-smart-flare/02-final/ios/Runner/AppDelegate.h b/003-smart-flare/02-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/003-smart-flare/02-final/ios/Runner/AppDelegate.m b/003-smart-flare/02-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/003-smart-flare/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/003-smart-flare/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/003-smart-flare/02-final/ios/Runner/Base.lproj/Main.storyboard b/003-smart-flare/02-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/003-smart-flare/02-final/ios/Runner/Info.plist b/003-smart-flare/02-final/ios/Runner/Info.plist new file mode 100644 index 00000000..33f64a5b --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flare_tutorial + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/003-smart-flare/02-final/ios/Runner/main.m b/003-smart-flare/02-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/003-smart-flare/02-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/003-smart-flare/02-final/lib/flare_demo.dart b/003-smart-flare/02-final/lib/flare_demo.dart index d10554ac..70025faf 100644 --- a/003-smart-flare/02-final/lib/flare_demo.dart +++ b/003-smart-flare/02-final/lib/flare_demo.dart @@ -1,71 +1,71 @@ -import 'package:flutter/material.dart'; -import 'package:smart_flare/smart_flare.dart'; - -class FlareDemo extends StatefulWidget { - @override - _FlareDemoState createState() => _FlareDemoState(); -} - -class _FlareDemoState extends State { - @override - Widget build(BuildContext context) { - var animationWidth = 295.0; - var animationHeight = 251.0; - var animationWidthThirds = animationWidth / 3; - var halfAnimationHeight =animationHeight / 2; - - var activeAreas = [ - - ActiveArea( - area: Rect.fromLTWH(0, 0, - animationWidthThirds, - halfAnimationHeight), - debugArea: true, - guardComingFrom: ['deactivate'], - animationName: 'camera_tapped'), - - ActiveArea( - area: Rect.fromLTWH( - animationWidthThirds, 0, - animationWidthThirds, - halfAnimationHeight), - debugArea: true, - guardComingFrom: ['deactivate'], - animationName: 'pulse_tapped'), - - ActiveArea( - area: Rect.fromLTWH( - animationWidthThirds * 2, 0, - animationWidthThirds, - halfAnimationHeight), - debugArea: true, - guardComingFrom: ['deactivate'], - animationName: 'image_tapped'), - - ActiveArea( - area: Rect.fromLTWH( - 0, - animationHeight/2, - animationWidth, - animationHeight/2), - debugArea: true, - animationsToCycle: ['activate', 'deactivate'], - onAreaTapped: () { - print('Button tapped!'); - }) - ]; - - - return Scaffold( - backgroundColor: Color.fromARGB(255, 102, 18, 222), - body: Align( - alignment: Alignment.bottomCenter, - child: SmartFlareActor( - width: animationWidth, - height: animationHeight, - filename: 'assets/button-animation.flr', - startingAnimation: 'deactivate', - activeAreas: activeAreas, - ))); - } -} +import 'package:flutter/material.dart'; +import 'package:smart_flare/smart_flare.dart'; + +class FlareDemo extends StatefulWidget { + @override + _FlareDemoState createState() => _FlareDemoState(); +} + +class _FlareDemoState extends State { + @override + Widget build(BuildContext context) { + var animationWidth = 295.0; + var animationHeight = 251.0; + var animationWidthThirds = animationWidth / 3; + var halfAnimationHeight =animationHeight / 2; + + var activeAreas = [ + + ActiveArea( + area: Rect.fromLTWH(0, 0, + animationWidthThirds, + halfAnimationHeight), + debugArea: true, + guardComingFrom: ['deactivate'], + animationName: 'camera_tapped'), + + ActiveArea( + area: Rect.fromLTWH( + animationWidthThirds, 0, + animationWidthThirds, + halfAnimationHeight), + debugArea: true, + guardComingFrom: ['deactivate'], + animationName: 'pulse_tapped'), + + ActiveArea( + area: Rect.fromLTWH( + animationWidthThirds * 2, 0, + animationWidthThirds, + halfAnimationHeight), + debugArea: true, + guardComingFrom: ['deactivate'], + animationName: 'image_tapped'), + + ActiveArea( + area: Rect.fromLTWH( + 0, + animationHeight/2, + animationWidth, + animationHeight/2), + debugArea: true, + animationsToCycle: ['activate', 'deactivate'], + onAreaTapped: () { + print('Button tapped!'); + }) + ]; + + + return Scaffold( + backgroundColor: Color.fromARGB(255, 102, 18, 222), + body: Align( + alignment: Alignment.bottomCenter, + child: SmartFlareActor( + width: animationWidth, + height: animationHeight, + filename: 'assets/button-animation.flr', + startingAnimation: 'deactivate', + activeAreas: activeAreas, + ))); + } +} diff --git a/003-smart-flare/02-final/lib/main.dart b/003-smart-flare/02-final/lib/main.dart index 0ff78fdc..425f74b5 100644 --- a/003-smart-flare/02-final/lib/main.dart +++ b/003-smart-flare/02-final/lib/main.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; -import 'flare_demo.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: FlareDemo()); - } -} +import 'package:flutter/material.dart'; +import 'flare_demo.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: FlareDemo()); + } +} diff --git a/003-smart-flare/02-final/pubspec.lock b/003-smart-flare/02-final/pubspec.lock index cbbc209f..c363c06e 100644 --- a/003-smart-flare/02-final/pubspec.lock +++ b/003-smart-flare/02-final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flare_dart: dependency: transitive description: @@ -80,21 +66,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -113,7 +113,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -127,14 +127,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -148,7 +148,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -164,4 +164,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/003-smart-flare/02-final/pubspec.yaml b/003-smart-flare/02-final/pubspec.yaml index 9e20101c..624d6280 100644 --- a/003-smart-flare/02-final/pubspec.yaml +++ b/003-smart-flare/02-final/pubspec.yaml @@ -1,68 +1,68 @@ -name: flare_tutorial -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - flare_flutter: any - smart_flare: any - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - assets: - - button-animation.flr - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flare_tutorial +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + flare_flutter: any + smart_flare: any + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + # To add assets to your application, add an assets section, like this: + assets: + - button-animation.flr + # - images/a_dot_ham.jpeg + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/004-flutter-basics/01-start/.gitignore b/004-flutter-basics/01-start/.gitignore index 5be59a14..07488ba6 100644 --- a/004-flutter-basics/01-start/.gitignore +++ b/004-flutter-basics/01-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/004-flutter-basics/01-start/.metadata b/004-flutter-basics/01-start/.metadata index faa3d297..56206c02 100644 --- a/004-flutter-basics/01-start/.metadata +++ b/004-flutter-basics/01-start/.metadata @@ -1,10 +1,10 @@ -# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 - channel: master - -project_type: app +# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 + channel: master + +project_type: app diff --git a/004-flutter-basics/01-start/README.md b/004-flutter-basics/01-start/README.md index 0e4b8187..d6e96c2e 100644 --- a/004-flutter-basics/01-start/README.md +++ b/004-flutter-basics/01-start/README.md @@ -1,3 +1,3 @@ -# Handling the basics in Flutter yourself - -In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. +# Handling the basics in Flutter yourself + +In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. diff --git a/004-flutter-basics/01-start/android/app/build.gradle b/004-flutter-basics/01-start/android/app/build.gradle new file mode 100644 index 00000000..5ff16e4a --- /dev/null +++ b/004-flutter-basics/01-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flutter_basics" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/004-flutter-basics/01-start/android/app/src/debug/AndroidManifest.xml b/004-flutter-basics/01-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/01-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/01-start/android/app/src/main/AndroidManifest.xml b/004-flutter-basics/01-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..21b93e97 --- /dev/null +++ b/004-flutter-basics/01-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/004-flutter-basics/01-start/android/app/src/main/java/com/example/flutter_basics/MainActivity.java b/004-flutter-basics/01-start/android/app/src/main/java/com/example/flutter_basics/MainActivity.java new file mode 100644 index 00000000..f4b72d18 --- /dev/null +++ b/004-flutter-basics/01-start/android/app/src/main/java/com/example/flutter_basics/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flutter_basics; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/004-flutter-basics/01-start/android/app/src/main/res/drawable/launch_background.xml b/004-flutter-basics/01-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/004-flutter-basics/01-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/004-flutter-basics/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/004-flutter-basics/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/004-flutter-basics/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/01-start/android/app/src/main/res/values/styles.xml b/004-flutter-basics/01-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/004-flutter-basics/01-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/004-flutter-basics/01-start/android/app/src/profile/AndroidManifest.xml b/004-flutter-basics/01-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/01-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/01-start/android/build.gradle b/004-flutter-basics/01-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/004-flutter-basics/01-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/004-flutter-basics/01-start/android/gradle.properties b/004-flutter-basics/01-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/004-flutter-basics/01-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/004-flutter-basics/01-start/android/gradle/wrapper/gradle-wrapper.properties b/004-flutter-basics/01-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/004-flutter-basics/01-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/004-flutter-basics/01-start/android/settings.gradle b/004-flutter-basics/01-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/004-flutter-basics/01-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/004-flutter-basics/01-start/ios/Flutter/AppFrameworkInfo.plist b/004-flutter-basics/01-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/004-flutter-basics/01-start/ios/Flutter/Debug.xcconfig b/004-flutter-basics/01-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/01-start/ios/Flutter/Release.xcconfig b/004-flutter-basics/01-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/01-start/ios/Runner.xcodeproj/project.pbxproj b/004-flutter-basics/01-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..a4acc097 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/004-flutter-basics/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/004-flutter-basics/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/01-start/ios/Runner/AppDelegate.h b/004-flutter-basics/01-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/004-flutter-basics/01-start/ios/Runner/AppDelegate.m b/004-flutter-basics/01-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/004-flutter-basics/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/004-flutter-basics/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/01-start/ios/Runner/Base.lproj/Main.storyboard b/004-flutter-basics/01-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/01-start/ios/Runner/Info.plist b/004-flutter-basics/01-start/ios/Runner/Info.plist new file mode 100644 index 00000000..9ebd03ff --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_basics + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/004-flutter-basics/01-start/ios/Runner/main.m b/004-flutter-basics/01-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/004-flutter-basics/01-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/004-flutter-basics/01-start/lib/home.dart b/004-flutter-basics/01-start/lib/home.dart index 20b8cf31..273b6f00 100644 --- a/004-flutter-basics/01-start/lib/home.dart +++ b/004-flutter-basics/01-start/lib/home.dart @@ -1,10 +1,10 @@ -import 'package:flutter/material.dart'; - -class Home extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container(), - ); - } +import 'package:flutter/material.dart'; + +class Home extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container(), + ); + } } \ No newline at end of file diff --git a/004-flutter-basics/01-start/lib/main.dart b/004-flutter-basics/01-start/lib/main.dart index 89b2557f..dde38547 100644 --- a/004-flutter-basics/01-start/lib/main.dart +++ b/004-flutter-basics/01-start/lib/main.dart @@ -1,18 +1,18 @@ -import 'package:flutter/material.dart'; -import './home.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Home() - ); - } -} +import 'package:flutter/material.dart'; +import './home.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Home() + ); + } +} diff --git a/004-flutter-basics/01-start/pubspec.lock b/004-flutter-basics/01-start/pubspec.lock index 066a096b..e6c59b03 100644 --- a/004-flutter-basics/01-start/pubspec.lock +++ b/004-flutter-basics/01-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -106,14 +106,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/004-flutter-basics/01-start/pubspec.yaml b/004-flutter-basics/01-start/pubspec.yaml index 72a1bdf6..b21162bc 100644 --- a/004-flutter-basics/01-start/pubspec.yaml +++ b/004-flutter-basics/01-start/pubspec.yaml @@ -1,66 +1,72 @@ -name: flutter_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flutter_basics +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/004-flutter-basics/01-start/test/widget_test.dart b/004-flutter-basics/01-start/test/widget_test.dart index 026977f3..cd87292c 100644 --- a/004-flutter-basics/01-start/test/widget_test.dart +++ b/004-flutter-basics/01-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_basics/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/004-flutter-basics/02-setState/.gitignore b/004-flutter-basics/02-setState/.gitignore index 5be59a14..07488ba6 100644 --- a/004-flutter-basics/02-setState/.gitignore +++ b/004-flutter-basics/02-setState/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/004-flutter-basics/02-setState/.metadata b/004-flutter-basics/02-setState/.metadata index faa3d297..56206c02 100644 --- a/004-flutter-basics/02-setState/.metadata +++ b/004-flutter-basics/02-setState/.metadata @@ -1,10 +1,10 @@ -# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 - channel: master - -project_type: app +# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 + channel: master + +project_type: app diff --git a/004-flutter-basics/02-setState/README.md b/004-flutter-basics/02-setState/README.md index 0e4b8187..d6e96c2e 100644 --- a/004-flutter-basics/02-setState/README.md +++ b/004-flutter-basics/02-setState/README.md @@ -1,3 +1,3 @@ -# Handling the basics in Flutter yourself - -In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. +# Handling the basics in Flutter yourself + +In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. diff --git a/004-flutter-basics/02-setState/android/app/build.gradle b/004-flutter-basics/02-setState/android/app/build.gradle new file mode 100644 index 00000000..5ff16e4a --- /dev/null +++ b/004-flutter-basics/02-setState/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flutter_basics" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/004-flutter-basics/02-setState/android/app/src/debug/AndroidManifest.xml b/004-flutter-basics/02-setState/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/02-setState/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/02-setState/android/app/src/main/AndroidManifest.xml b/004-flutter-basics/02-setState/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..21b93e97 --- /dev/null +++ b/004-flutter-basics/02-setState/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/004-flutter-basics/02-setState/android/app/src/main/java/com/example/flutter_basics/MainActivity.java b/004-flutter-basics/02-setState/android/app/src/main/java/com/example/flutter_basics/MainActivity.java new file mode 100644 index 00000000..f4b72d18 --- /dev/null +++ b/004-flutter-basics/02-setState/android/app/src/main/java/com/example/flutter_basics/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flutter_basics; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/004-flutter-basics/02-setState/android/app/src/main/res/drawable/launch_background.xml b/004-flutter-basics/02-setState/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/004-flutter-basics/02-setState/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/004-flutter-basics/02-setState/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/02-setState/android/app/src/main/res/values/styles.xml b/004-flutter-basics/02-setState/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/004-flutter-basics/02-setState/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/004-flutter-basics/02-setState/android/app/src/profile/AndroidManifest.xml b/004-flutter-basics/02-setState/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/02-setState/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/02-setState/android/build.gradle b/004-flutter-basics/02-setState/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/004-flutter-basics/02-setState/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/004-flutter-basics/02-setState/android/gradle.properties b/004-flutter-basics/02-setState/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/004-flutter-basics/02-setState/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/004-flutter-basics/02-setState/android/gradle/wrapper/gradle-wrapper.properties b/004-flutter-basics/02-setState/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/004-flutter-basics/02-setState/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/004-flutter-basics/02-setState/android/settings.gradle b/004-flutter-basics/02-setState/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/004-flutter-basics/02-setState/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/004-flutter-basics/02-setState/ios/Flutter/AppFrameworkInfo.plist b/004-flutter-basics/02-setState/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/004-flutter-basics/02-setState/ios/Flutter/Debug.xcconfig b/004-flutter-basics/02-setState/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/02-setState/ios/Flutter/Release.xcconfig b/004-flutter-basics/02-setState/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/02-setState/ios/Runner.xcodeproj/project.pbxproj b/004-flutter-basics/02-setState/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..a4acc097 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/004-flutter-basics/02-setState/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/02-setState/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/02-setState/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/004-flutter-basics/02-setState/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/02-setState/ios/Runner.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/02-setState/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/02-setState/ios/Runner/AppDelegate.h b/004-flutter-basics/02-setState/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/004-flutter-basics/02-setState/ios/Runner/AppDelegate.m b/004-flutter-basics/02-setState/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/004-flutter-basics/02-setState/ios/Runner/Base.lproj/LaunchScreen.storyboard b/004-flutter-basics/02-setState/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/02-setState/ios/Runner/Base.lproj/Main.storyboard b/004-flutter-basics/02-setState/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/02-setState/ios/Runner/Info.plist b/004-flutter-basics/02-setState/ios/Runner/Info.plist new file mode 100644 index 00000000..9ebd03ff --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_basics + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/004-flutter-basics/02-setState/ios/Runner/main.m b/004-flutter-basics/02-setState/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/004-flutter-basics/02-setState/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/004-flutter-basics/02-setState/lib/home.dart b/004-flutter-basics/02-setState/lib/home.dart index 88ad8d9f..2bacf4e8 100644 --- a/004-flutter-basics/02-setState/lib/home.dart +++ b/004-flutter-basics/02-setState/lib/home.dart @@ -1,72 +1,72 @@ -import 'package:flutter/material.dart'; - -class Home extends StatefulWidget { - @override - _HomeState createState() => _HomeState(); -} - -class _HomeState extends State { - - List _pageData; - - bool get _fetchingData => _pageData == null; - - @override - void initState() { - _getListData(hasError: true).then((data) => - setState(() { - if(data.length == 0) { - data.add('No data found for your account. Add something and check back.'); - } - _pageData = data; - })) - .catchError((error) => - setState((){ - _pageData = [error]; - })); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.grey[900], - body: _fetchingData - ? Center(child: CircularProgressIndicator()) - : ListView.builder( - itemCount: _pageData.length, - itemBuilder: (buildContext, index) =>_getListItemUi(index) - )); - } - - Widget _getListItemUi(int index) { - return Container( - margin: EdgeInsets.all(5.0), - height: 50.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Colors.grey[600] - ), - child: Center( - child: Text(_pageData[index], style: TextStyle(color: Colors.white,), - ), - ), - ); - } - - Future> _getListData({ - bool hasError = false, - bool hasData = true}) async { - await Future.delayed(Duration(seconds: 2)); - - if(hasError) { - return Future.error('An error occurred while fetching the data. Please try again later.'); - } - - if(!hasData) { - return List(); - } - - return List.generate(10, (index) => '$index title'); - } -} +import 'package:flutter/material.dart'; + +class Home extends StatefulWidget { + @override + _HomeState createState() => _HomeState(); +} + +class _HomeState extends State { + + List _pageData; + + bool get _fetchingData => _pageData == null; + + @override + void initState() { + _getListData(hasError: true).then((data) => + setState(() { + if(data.length == 0) { + data.add('No data found for your account. Add something and check back.'); + } + _pageData = data; + })) + .catchError((error) => + setState((){ + _pageData = [error]; + })); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.grey[900], + body: _fetchingData + ? Center(child: CircularProgressIndicator()) + : ListView.builder( + itemCount: _pageData.length, + itemBuilder: (buildContext, index) =>_getListItemUi(index) + )); + } + + Widget _getListItemUi(int index) { + return Container( + margin: EdgeInsets.all(5.0), + height: 50.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: Colors.grey[600] + ), + child: Center( + child: Text(_pageData[index], style: TextStyle(color: Colors.white,), + ), + ), + ); + } + + Future> _getListData({ + bool hasError = false, + bool hasData = true}) async { + await Future.delayed(Duration(seconds: 2)); + + if(hasError) { + return Future.error('An error occurred while fetching the data. Please try again later.'); + } + + if(!hasData) { + return List(); + } + + return List.generate(10, (index) => '$index title'); + } +} diff --git a/004-flutter-basics/02-setState/lib/main.dart b/004-flutter-basics/02-setState/lib/main.dart index 89b2557f..dde38547 100644 --- a/004-flutter-basics/02-setState/lib/main.dart +++ b/004-flutter-basics/02-setState/lib/main.dart @@ -1,18 +1,18 @@ -import 'package:flutter/material.dart'; -import './home.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Home() - ); - } -} +import 'package:flutter/material.dart'; +import './home.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Home() + ); + } +} diff --git a/004-flutter-basics/02-setState/pubspec.lock b/004-flutter-basics/02-setState/pubspec.lock index 066a096b..e6c59b03 100644 --- a/004-flutter-basics/02-setState/pubspec.lock +++ b/004-flutter-basics/02-setState/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -106,14 +106,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/004-flutter-basics/02-setState/pubspec.yaml b/004-flutter-basics/02-setState/pubspec.yaml index 72a1bdf6..b21162bc 100644 --- a/004-flutter-basics/02-setState/pubspec.yaml +++ b/004-flutter-basics/02-setState/pubspec.yaml @@ -1,66 +1,72 @@ -name: flutter_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flutter_basics +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/004-flutter-basics/02-setState/test/widget_test.dart b/004-flutter-basics/02-setState/test/widget_test.dart index 026977f3..cd87292c 100644 --- a/004-flutter-basics/02-setState/test/widget_test.dart +++ b/004-flutter-basics/02-setState/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_basics/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/004-flutter-basics/03-futureBuilder/.gitignore b/004-flutter-basics/03-futureBuilder/.gitignore index 5be59a14..07488ba6 100644 --- a/004-flutter-basics/03-futureBuilder/.gitignore +++ b/004-flutter-basics/03-futureBuilder/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/004-flutter-basics/03-futureBuilder/.metadata b/004-flutter-basics/03-futureBuilder/.metadata index faa3d297..56206c02 100644 --- a/004-flutter-basics/03-futureBuilder/.metadata +++ b/004-flutter-basics/03-futureBuilder/.metadata @@ -1,10 +1,10 @@ -# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 - channel: master - -project_type: app +# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 + channel: master + +project_type: app diff --git a/004-flutter-basics/03-futureBuilder/README.md b/004-flutter-basics/03-futureBuilder/README.md index 0e4b8187..d6e96c2e 100644 --- a/004-flutter-basics/03-futureBuilder/README.md +++ b/004-flutter-basics/03-futureBuilder/README.md @@ -1,3 +1,3 @@ -# Handling the basics in Flutter yourself - -In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. +# Handling the basics in Flutter yourself + +In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. diff --git a/004-flutter-basics/03-futureBuilder/android/app/build.gradle b/004-flutter-basics/03-futureBuilder/android/app/build.gradle new file mode 100644 index 00000000..5ff16e4a --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flutter_basics" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/debug/AndroidManifest.xml b/004-flutter-basics/03-futureBuilder/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/AndroidManifest.xml b/004-flutter-basics/03-futureBuilder/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..21b93e97 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/java/com/example/flutter_basics/MainActivity.java b/004-flutter-basics/03-futureBuilder/android/app/src/main/java/com/example/flutter_basics/MainActivity.java new file mode 100644 index 00000000..f4b72d18 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/app/src/main/java/com/example/flutter_basics/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flutter_basics; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/res/drawable/launch_background.xml b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/main/res/values/styles.xml b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/004-flutter-basics/03-futureBuilder/android/app/src/profile/AndroidManifest.xml b/004-flutter-basics/03-futureBuilder/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/03-futureBuilder/android/build.gradle b/004-flutter-basics/03-futureBuilder/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/004-flutter-basics/03-futureBuilder/android/gradle.properties b/004-flutter-basics/03-futureBuilder/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/004-flutter-basics/03-futureBuilder/android/gradle/wrapper/gradle-wrapper.properties b/004-flutter-basics/03-futureBuilder/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/004-flutter-basics/03-futureBuilder/android/settings.gradle b/004-flutter-basics/03-futureBuilder/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/004-flutter-basics/03-futureBuilder/ios/Flutter/AppFrameworkInfo.plist b/004-flutter-basics/03-futureBuilder/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/004-flutter-basics/03-futureBuilder/ios/Flutter/Debug.xcconfig b/004-flutter-basics/03-futureBuilder/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/03-futureBuilder/ios/Flutter/Release.xcconfig b/004-flutter-basics/03-futureBuilder/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/project.pbxproj b/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..a4acc097 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/03-futureBuilder/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/AppDelegate.h b/004-flutter-basics/03-futureBuilder/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/AppDelegate.m b/004-flutter-basics/03-futureBuilder/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Base.lproj/LaunchScreen.storyboard b/004-flutter-basics/03-futureBuilder/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Base.lproj/Main.storyboard b/004-flutter-basics/03-futureBuilder/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/Info.plist b/004-flutter-basics/03-futureBuilder/ios/Runner/Info.plist new file mode 100644 index 00000000..9ebd03ff --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_basics + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/004-flutter-basics/03-futureBuilder/ios/Runner/main.m b/004-flutter-basics/03-futureBuilder/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/004-flutter-basics/03-futureBuilder/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/004-flutter-basics/03-futureBuilder/lib/home.dart b/004-flutter-basics/03-futureBuilder/lib/home.dart index bfcbf1c8..2ff54133 100644 --- a/004-flutter-basics/03-futureBuilder/lib/home.dart +++ b/004-flutter-basics/03-futureBuilder/lib/home.dart @@ -1,77 +1,77 @@ -import 'package:flutter/material.dart'; - -class Home extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - floatingActionButton: FloatingActionButton(onPressed: () { - // We want to refresh, but this actually does nothing. Which is the limitation - _getListData(); - }), - backgroundColor: Colors.grey[900], - body: FutureBuilder( - future: _getListData(), - builder: (buildContext, snapshot) { - - if(snapshot.hasError) { - return _getInformationMessage(snapshot.error); - } - - if (!snapshot.hasData) { - return Center(child: CircularProgressIndicator()); - } - - var listItems = snapshot.data; - if(listItems.length == 0) { - return _getInformationMessage('No data found for your account. Add something and check back.'); - } - - return ListView.builder( - itemCount: listItems.length, - itemBuilder: (buildContext, index) => _getListItemUi(index, listItems)); - } - )); - } - - Widget _getListItemUi(int index, List listItems) { - return Container( - margin: EdgeInsets.all(5.0), - height: 50.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: Colors.grey[600]), - child: Center( - child: Text( - listItems[index], - style: TextStyle( - color: Colors.white, - ), - ), - ), - ); - } - - Widget _getInformationMessage(String message) { - return Center( - child: Text( - message, - textAlign: TextAlign.center, - style: TextStyle(fontWeight: FontWeight.w900, color: Colors.grey[500]), - )); - } - - Future> _getListData( - {bool hasError = false, bool hasData = true}) async { - await Future.delayed(Duration(seconds: 2)); - - if (hasError) { - return Future.error( - 'An error occurred while fetching the data. Please try again later.'); - } - - if (!hasData) { - return List(); - } - - return List.generate(10, (index) => '$index title'); - } -} +import 'package:flutter/material.dart'; + +class Home extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: FloatingActionButton(onPressed: () { + // We want to refresh, but this actually does nothing. Which is the limitation + _getListData(); + }), + backgroundColor: Colors.grey[900], + body: FutureBuilder( + future: _getListData(), + builder: (buildContext, snapshot) { + + if(snapshot.hasError) { + return _getInformationMessage(snapshot.error); + } + + if (!snapshot.hasData) { + return Center(child: CircularProgressIndicator()); + } + + var listItems = snapshot.data; + if(listItems.length == 0) { + return _getInformationMessage('No data found for your account. Add something and check back.'); + } + + return ListView.builder( + itemCount: listItems.length, + itemBuilder: (buildContext, index) => _getListItemUi(index, listItems)); + } + )); + } + + Widget _getListItemUi(int index, List listItems) { + return Container( + margin: EdgeInsets.all(5.0), + height: 50.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: Colors.grey[600]), + child: Center( + child: Text( + listItems[index], + style: TextStyle( + color: Colors.white, + ), + ), + ), + ); + } + + Widget _getInformationMessage(String message) { + return Center( + child: Text( + message, + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w900, color: Colors.grey[500]), + )); + } + + Future> _getListData( + {bool hasError = false, bool hasData = true}) async { + await Future.delayed(Duration(seconds: 2)); + + if (hasError) { + return Future.error( + 'An error occurred while fetching the data. Please try again later.'); + } + + if (!hasData) { + return List(); + } + + return List.generate(10, (index) => '$index title'); + } +} diff --git a/004-flutter-basics/03-futureBuilder/lib/main.dart b/004-flutter-basics/03-futureBuilder/lib/main.dart index 89b2557f..dde38547 100644 --- a/004-flutter-basics/03-futureBuilder/lib/main.dart +++ b/004-flutter-basics/03-futureBuilder/lib/main.dart @@ -1,18 +1,18 @@ -import 'package:flutter/material.dart'; -import './home.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Home() - ); - } -} +import 'package:flutter/material.dart'; +import './home.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Home() + ); + } +} diff --git a/004-flutter-basics/03-futureBuilder/pubspec.lock b/004-flutter-basics/03-futureBuilder/pubspec.lock index 066a096b..e6c59b03 100644 --- a/004-flutter-basics/03-futureBuilder/pubspec.lock +++ b/004-flutter-basics/03-futureBuilder/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -106,14 +106,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/004-flutter-basics/03-futureBuilder/pubspec.yaml b/004-flutter-basics/03-futureBuilder/pubspec.yaml index 72a1bdf6..b21162bc 100644 --- a/004-flutter-basics/03-futureBuilder/pubspec.yaml +++ b/004-flutter-basics/03-futureBuilder/pubspec.yaml @@ -1,66 +1,72 @@ -name: flutter_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flutter_basics +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/004-flutter-basics/03-futureBuilder/test/widget_test.dart b/004-flutter-basics/03-futureBuilder/test/widget_test.dart index 026977f3..cd87292c 100644 --- a/004-flutter-basics/03-futureBuilder/test/widget_test.dart +++ b/004-flutter-basics/03-futureBuilder/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_basics/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/004-flutter-basics/04-streamBuilder/.gitignore b/004-flutter-basics/04-streamBuilder/.gitignore index 5be59a14..07488ba6 100644 --- a/004-flutter-basics/04-streamBuilder/.gitignore +++ b/004-flutter-basics/04-streamBuilder/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/004-flutter-basics/04-streamBuilder/.metadata b/004-flutter-basics/04-streamBuilder/.metadata index faa3d297..56206c02 100644 --- a/004-flutter-basics/04-streamBuilder/.metadata +++ b/004-flutter-basics/04-streamBuilder/.metadata @@ -1,10 +1,10 @@ -# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 - channel: master - -project_type: app +# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 + channel: master + +project_type: app diff --git a/004-flutter-basics/04-streamBuilder/README.md b/004-flutter-basics/04-streamBuilder/README.md index 0e4b8187..d6e96c2e 100644 --- a/004-flutter-basics/04-streamBuilder/README.md +++ b/004-flutter-basics/04-streamBuilder/README.md @@ -1,3 +1,3 @@ -# Handling the basics in Flutter yourself - -In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. +# Handling the basics in Flutter yourself + +In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. diff --git a/004-flutter-basics/04-streamBuilder/android/app/build.gradle b/004-flutter-basics/04-streamBuilder/android/app/build.gradle new file mode 100644 index 00000000..5ff16e4a --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flutter_basics" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/debug/AndroidManifest.xml b/004-flutter-basics/04-streamBuilder/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/AndroidManifest.xml b/004-flutter-basics/04-streamBuilder/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..21b93e97 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/java/com/example/flutter_basics/MainActivity.java b/004-flutter-basics/04-streamBuilder/android/app/src/main/java/com/example/flutter_basics/MainActivity.java new file mode 100644 index 00000000..f4b72d18 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/app/src/main/java/com/example/flutter_basics/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flutter_basics; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/res/drawable/launch_background.xml b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/main/res/values/styles.xml b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/004-flutter-basics/04-streamBuilder/android/app/src/profile/AndroidManifest.xml b/004-flutter-basics/04-streamBuilder/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/04-streamBuilder/android/build.gradle b/004-flutter-basics/04-streamBuilder/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/004-flutter-basics/04-streamBuilder/android/gradle.properties b/004-flutter-basics/04-streamBuilder/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/004-flutter-basics/04-streamBuilder/android/gradle/wrapper/gradle-wrapper.properties b/004-flutter-basics/04-streamBuilder/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/004-flutter-basics/04-streamBuilder/android/settings.gradle b/004-flutter-basics/04-streamBuilder/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/004-flutter-basics/04-streamBuilder/ios/Flutter/AppFrameworkInfo.plist b/004-flutter-basics/04-streamBuilder/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/004-flutter-basics/04-streamBuilder/ios/Flutter/Debug.xcconfig b/004-flutter-basics/04-streamBuilder/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/04-streamBuilder/ios/Flutter/Release.xcconfig b/004-flutter-basics/04-streamBuilder/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/project.pbxproj b/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..a4acc097 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/04-streamBuilder/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/AppDelegate.h b/004-flutter-basics/04-streamBuilder/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/AppDelegate.m b/004-flutter-basics/04-streamBuilder/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Base.lproj/LaunchScreen.storyboard b/004-flutter-basics/04-streamBuilder/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Base.lproj/Main.storyboard b/004-flutter-basics/04-streamBuilder/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/Info.plist b/004-flutter-basics/04-streamBuilder/ios/Runner/Info.plist new file mode 100644 index 00000000..9ebd03ff --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_basics + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/004-flutter-basics/04-streamBuilder/ios/Runner/main.m b/004-flutter-basics/04-streamBuilder/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/004-flutter-basics/04-streamBuilder/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/004-flutter-basics/04-streamBuilder/lib/home.dart b/004-flutter-basics/04-streamBuilder/lib/home.dart index 196ab9a1..bf84da07 100644 --- a/004-flutter-basics/04-streamBuilder/lib/home.dart +++ b/004-flutter-basics/04-streamBuilder/lib/home.dart @@ -1,96 +1,96 @@ -import 'package:flutter/material.dart'; -import 'dart:async'; - -enum HomeViewState { Busy, DataRetrieved, NoData } - -class Home extends StatefulWidget { - @override - _HomeState createState() => _HomeState(); -} - -class _HomeState extends State { - final StreamController stateController = StreamController(); - List listItems; - - @override - void initState() { - _getListData(); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - floatingActionButton: FloatingActionButton(onPressed: () { - // We want to refresh, but this actually does nothing. Which is the limitation - _getListData(); - }), - backgroundColor: Colors.grey[900], - body: StreamBuilder( - stream: stateController.stream, - builder: (buildContext, snapshot) { - if (snapshot.hasError) { - return _getInformationMessage(snapshot.error); - } - - // Use busy indicator instead of hasData from snapShot - if (!snapshot.hasData || snapshot.data == HomeViewState.Busy) { - return Center(child: CircularProgressIndicator()); - } - - // use explicit state instead of checking the lenght - if (snapshot.data == HomeViewState.NoData) { - return _getInformationMessage( - 'No data found for your account. Add something and check back.'); - } - - return ListView.builder( - itemCount: listItems.length, - itemBuilder: (buildContext, index) => - _getListItemUi(index, listItems)); - })); - } - - Widget _getListItemUi(int index, List listItems) { - return Container( - margin: EdgeInsets.all(5.0), - height: 50.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: Colors.grey[600]), - child: Center( - child: Text( - listItems[index], - style: TextStyle( - color: Colors.white, - ), - ), - ), - ); - } - - Widget _getInformationMessage(String message) { - return Center( - child: Text( - message, - textAlign: TextAlign.center, - style: TextStyle(fontWeight: FontWeight.w900, color: Colors.grey[500]), - )); - } - - Future _getListData({bool hasError = false, bool hasData = true}) async { - stateController.add(HomeViewState.Busy); - await Future.delayed(Duration(seconds: 2)); - - if (hasError) { - return stateController.addError( - 'An error occurred while fetching the data. Please try again later.'); - } - - if (!hasData) { - return stateController.add(HomeViewState.NoData); - } - - listItems = List.generate(10, (index) => '$index title'); - stateController.add(HomeViewState.DataRetrieved); - } -} +import 'package:flutter/material.dart'; +import 'dart:async'; + +enum HomeViewState { Busy, DataRetrieved, NoData } + +class Home extends StatefulWidget { + @override + _HomeState createState() => _HomeState(); +} + +class _HomeState extends State { + final StreamController stateController = StreamController(); + List listItems; + + @override + void initState() { + _getListData(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: FloatingActionButton(onPressed: () { + // We want to refresh, but this actually does nothing. Which is the limitation + _getListData(); + }), + backgroundColor: Colors.grey[900], + body: StreamBuilder( + stream: stateController.stream, + builder: (buildContext, snapshot) { + if (snapshot.hasError) { + return _getInformationMessage(snapshot.error); + } + + // Use busy indicator instead of hasData from snapShot + if (!snapshot.hasData || snapshot.data == HomeViewState.Busy) { + return Center(child: CircularProgressIndicator()); + } + + // use explicit state instead of checking the lenght + if (snapshot.data == HomeViewState.NoData) { + return _getInformationMessage( + 'No data found for your account. Add something and check back.'); + } + + return ListView.builder( + itemCount: listItems.length, + itemBuilder: (buildContext, index) => + _getListItemUi(index, listItems)); + })); + } + + Widget _getListItemUi(int index, List listItems) { + return Container( + margin: EdgeInsets.all(5.0), + height: 50.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: Colors.grey[600]), + child: Center( + child: Text( + listItems[index], + style: TextStyle( + color: Colors.white, + ), + ), + ), + ); + } + + Widget _getInformationMessage(String message) { + return Center( + child: Text( + message, + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w900, color: Colors.grey[500]), + )); + } + + Future _getListData({bool hasError = false, bool hasData = true}) async { + stateController.add(HomeViewState.Busy); + await Future.delayed(Duration(seconds: 2)); + + if (hasError) { + return stateController.addError( + 'An error occurred while fetching the data. Please try again later.'); + } + + if (!hasData) { + return stateController.add(HomeViewState.NoData); + } + + listItems = List.generate(10, (index) => '$index title'); + stateController.add(HomeViewState.DataRetrieved); + } +} diff --git a/004-flutter-basics/04-streamBuilder/lib/main.dart b/004-flutter-basics/04-streamBuilder/lib/main.dart index 89b2557f..dde38547 100644 --- a/004-flutter-basics/04-streamBuilder/lib/main.dart +++ b/004-flutter-basics/04-streamBuilder/lib/main.dart @@ -1,18 +1,18 @@ -import 'package:flutter/material.dart'; -import './home.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Home() - ); - } -} +import 'package:flutter/material.dart'; +import './home.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Home() + ); + } +} diff --git a/004-flutter-basics/04-streamBuilder/pubspec.lock b/004-flutter-basics/04-streamBuilder/pubspec.lock index 066a096b..e6c59b03 100644 --- a/004-flutter-basics/04-streamBuilder/pubspec.lock +++ b/004-flutter-basics/04-streamBuilder/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -106,14 +106,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/004-flutter-basics/04-streamBuilder/pubspec.yaml b/004-flutter-basics/04-streamBuilder/pubspec.yaml index 72a1bdf6..b21162bc 100644 --- a/004-flutter-basics/04-streamBuilder/pubspec.yaml +++ b/004-flutter-basics/04-streamBuilder/pubspec.yaml @@ -1,66 +1,72 @@ -name: flutter_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flutter_basics +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/004-flutter-basics/04-streamBuilder/test/widget_test.dart b/004-flutter-basics/04-streamBuilder/test/widget_test.dart index 026977f3..cd87292c 100644 --- a/004-flutter-basics/04-streamBuilder/test/widget_test.dart +++ b/004-flutter-basics/04-streamBuilder/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_basics/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/004-flutter-basics/05-view-model/.gitignore b/004-flutter-basics/05-view-model/.gitignore index 5be59a14..07488ba6 100644 --- a/004-flutter-basics/05-view-model/.gitignore +++ b/004-flutter-basics/05-view-model/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/004-flutter-basics/05-view-model/.metadata b/004-flutter-basics/05-view-model/.metadata index faa3d297..56206c02 100644 --- a/004-flutter-basics/05-view-model/.metadata +++ b/004-flutter-basics/05-view-model/.metadata @@ -1,10 +1,10 @@ -# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 - channel: master - -project_type: app +# 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: 64a28e3685bee310e697a91612d7e30d0426cda2 + channel: master + +project_type: app diff --git a/004-flutter-basics/05-view-model/README.md b/004-flutter-basics/05-view-model/README.md index 0e4b8187..d6e96c2e 100644 --- a/004-flutter-basics/05-view-model/README.md +++ b/004-flutter-basics/05-view-model/README.md @@ -1,3 +1,3 @@ -# Handling the basics in Flutter yourself - -In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. +# Handling the basics in Flutter yourself + +In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. diff --git a/004-flutter-basics/05-view-model/android/app/build.gradle b/004-flutter-basics/05-view-model/android/app/build.gradle new file mode 100644 index 00000000..5ff16e4a --- /dev/null +++ b/004-flutter-basics/05-view-model/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flutter_basics" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/004-flutter-basics/05-view-model/android/app/src/debug/AndroidManifest.xml b/004-flutter-basics/05-view-model/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/05-view-model/android/app/src/main/AndroidManifest.xml b/004-flutter-basics/05-view-model/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..21b93e97 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/004-flutter-basics/05-view-model/android/app/src/main/java/com/example/flutter_basics/MainActivity.java b/004-flutter-basics/05-view-model/android/app/src/main/java/com/example/flutter_basics/MainActivity.java new file mode 100644 index 00000000..f4b72d18 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/app/src/main/java/com/example/flutter_basics/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flutter_basics; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/004-flutter-basics/05-view-model/android/app/src/main/res/drawable/launch_background.xml b/004-flutter-basics/05-view-model/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/004-flutter-basics/05-view-model/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/004-flutter-basics/05-view-model/android/app/src/main/res/values/styles.xml b/004-flutter-basics/05-view-model/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/004-flutter-basics/05-view-model/android/app/src/profile/AndroidManifest.xml b/004-flutter-basics/05-view-model/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..a490e622 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/004-flutter-basics/05-view-model/android/build.gradle b/004-flutter-basics/05-view-model/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/004-flutter-basics/05-view-model/android/gradle.properties b/004-flutter-basics/05-view-model/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/004-flutter-basics/05-view-model/android/gradle/wrapper/gradle-wrapper.properties b/004-flutter-basics/05-view-model/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/004-flutter-basics/05-view-model/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/004-flutter-basics/05-view-model/android/settings.gradle b/004-flutter-basics/05-view-model/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/004-flutter-basics/05-view-model/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/004-flutter-basics/05-view-model/ios/Flutter/AppFrameworkInfo.plist b/004-flutter-basics/05-view-model/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/004-flutter-basics/05-view-model/ios/Flutter/Debug.xcconfig b/004-flutter-basics/05-view-model/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/05-view-model/ios/Flutter/Release.xcconfig b/004-flutter-basics/05-view-model/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/project.pbxproj b/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..a4acc097 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterBasics; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/05-view-model/ios/Runner.xcworkspace/contents.xcworkspacedata b/004-flutter-basics/05-view-model/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/004-flutter-basics/05-view-model/ios/Runner/AppDelegate.h b/004-flutter-basics/05-view-model/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/004-flutter-basics/05-view-model/ios/Runner/AppDelegate.m b/004-flutter-basics/05-view-model/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/004-flutter-basics/05-view-model/ios/Runner/Base.lproj/LaunchScreen.storyboard b/004-flutter-basics/05-view-model/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/05-view-model/ios/Runner/Base.lproj/Main.storyboard b/004-flutter-basics/05-view-model/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/004-flutter-basics/05-view-model/ios/Runner/Info.plist b/004-flutter-basics/05-view-model/ios/Runner/Info.plist new file mode 100644 index 00000000..9ebd03ff --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_basics + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/004-flutter-basics/05-view-model/ios/Runner/main.m b/004-flutter-basics/05-view-model/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/004-flutter-basics/05-view-model/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/004-flutter-basics/05-view-model/lib/home.dart b/004-flutter-basics/05-view-model/lib/home.dart index 430ebba1..dc557f41 100644 --- a/004-flutter-basics/05-view-model/lib/home.dart +++ b/004-flutter-basics/05-view-model/lib/home.dart @@ -1,76 +1,76 @@ -import 'package:flutter/material.dart'; -import './home_model.dart'; - -class Home extends StatefulWidget { - @override - _HomeState createState() => _HomeState(); -} - -class _HomeState extends State { - final model = HomeModel(); - - @override - void initState() { - model.getListData(); - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - floatingActionButton: FloatingActionButton(onPressed: () { - // We want to refresh, but this actually does nothing. Which is the limitation - model.getListData(); - }), - backgroundColor: Colors.grey[900], - body: StreamBuilder( - stream: model.homeState, - builder: (buildContext, snapshot) { - if (snapshot.hasError) { - return _getInformationMessage(snapshot.error); - } - - // Use busy indicator instead of hasData from snapShot - if (!snapshot.hasData || snapshot.data == HomeViewState.Busy) { - return Center(child: CircularProgressIndicator()); - } - - // use explicit state instead of checking the lenght - if (snapshot.data == HomeViewState.NoData) { - return _getInformationMessage( - 'No data found for your account. Add something and check back.'); - } - - return ListView.builder( - itemCount: model.listItems.length, - itemBuilder: (buildContext, index) => - _getListItemUi(index, model.listItems)); - })); - } - - Widget _getListItemUi(int index, List listItems) { - return Container( - margin: EdgeInsets.all(5.0), - height: 50.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: Colors.grey[600]), - child: Center( - child: Text( - listItems[index], - style: TextStyle( - color: Colors.white, - ), - ), - ), - ); - } - - Widget _getInformationMessage(String message) { - return Center( - child: Text( - message, - textAlign: TextAlign.center, - style: TextStyle(fontWeight: FontWeight.w900, color: Colors.grey[500]), - )); - } -} +import 'package:flutter/material.dart'; +import './home_model.dart'; + +class Home extends StatefulWidget { + @override + _HomeState createState() => _HomeState(); +} + +class _HomeState extends State { + final model = HomeModel(); + + @override + void initState() { + model.getListData(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: FloatingActionButton(onPressed: () { + // We want to refresh, but this actually does nothing. Which is the limitation + model.getListData(); + }), + backgroundColor: Colors.grey[900], + body: StreamBuilder( + stream: model.homeState, + builder: (buildContext, snapshot) { + if (snapshot.hasError) { + return _getInformationMessage(snapshot.error); + } + + // Use busy indicator instead of hasData from snapShot + if (!snapshot.hasData || snapshot.data == HomeViewState.Busy) { + return Center(child: CircularProgressIndicator()); + } + + // use explicit state instead of checking the lenght + if (snapshot.data == HomeViewState.NoData) { + return _getInformationMessage( + 'No data found for your account. Add something and check back.'); + } + + return ListView.builder( + itemCount: model.listItems.length, + itemBuilder: (buildContext, index) => + _getListItemUi(index, model.listItems)); + })); + } + + Widget _getListItemUi(int index, List listItems) { + return Container( + margin: EdgeInsets.all(5.0), + height: 50.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: Colors.grey[600]), + child: Center( + child: Text( + listItems[index], + style: TextStyle( + color: Colors.white, + ), + ), + ), + ); + } + + Widget _getInformationMessage(String message) { + return Center( + child: Text( + message, + textAlign: TextAlign.center, + style: TextStyle(fontWeight: FontWeight.w900, color: Colors.grey[500]), + )); + } +} diff --git a/004-flutter-basics/05-view-model/lib/home_model.dart b/004-flutter-basics/05-view-model/lib/home_model.dart index 58c46788..33c26fa3 100644 --- a/004-flutter-basics/05-view-model/lib/home_model.dart +++ b/004-flutter-basics/05-view-model/lib/home_model.dart @@ -1,33 +1,33 @@ -import 'dart:async'; - -enum HomeViewState { Busy, DataRetrieved, NoData } - -class HomeModel { - - // Controller for the stream - final StreamController _stateController = StreamController(); - - // Items that are retrieved - List listItems; - - // Stream that broadcasts the home state - Stream get homeState => _stateController.stream; - - // Actual business logic - Future getListData({bool hasError = false, bool hasData = true}) async { - _stateController.add(HomeViewState.Busy); - await Future.delayed(Duration(seconds: 2)); - - if (hasError) { - return _stateController.addError( - 'An error occurred while fetching the data. Please try again later.'); - } - - if (!hasData) { - return _stateController.add(HomeViewState.NoData); - } - - listItems = List.generate(10, (index) => '$index title'); - _stateController.add(HomeViewState.DataRetrieved); - } +import 'dart:async'; + +enum HomeViewState { Busy, DataRetrieved, NoData } + +class HomeModel { + + // Controller for the stream + final StreamController _stateController = StreamController(); + + // Items that are retrieved + List listItems; + + // Stream that broadcasts the home state + Stream get homeState => _stateController.stream; + + // Actual business logic + Future getListData({bool hasError = false, bool hasData = true}) async { + _stateController.add(HomeViewState.Busy); + await Future.delayed(Duration(seconds: 2)); + + if (hasError) { + return _stateController.addError( + 'An error occurred while fetching the data. Please try again later.'); + } + + if (!hasData) { + return _stateController.add(HomeViewState.NoData); + } + + listItems = List.generate(10, (index) => '$index title'); + _stateController.add(HomeViewState.DataRetrieved); + } } \ No newline at end of file diff --git a/004-flutter-basics/05-view-model/lib/main.dart b/004-flutter-basics/05-view-model/lib/main.dart index 89b2557f..dde38547 100644 --- a/004-flutter-basics/05-view-model/lib/main.dart +++ b/004-flutter-basics/05-view-model/lib/main.dart @@ -1,18 +1,18 @@ -import 'package:flutter/material.dart'; -import './home.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Home() - ); - } -} +import 'package:flutter/material.dart'; +import './home.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Home() + ); + } +} diff --git a/004-flutter-basics/05-view-model/pubspec.lock b/004-flutter-basics/05-view-model/pubspec.lock index 066a096b..e6c59b03 100644 --- a/004-flutter-basics/05-view-model/pubspec.lock +++ b/004-flutter-basics/05-view-model/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.3+1" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -106,14 +106,14 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.2" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/004-flutter-basics/05-view-model/pubspec.yaml b/004-flutter-basics/05-view-model/pubspec.yaml index 72a1bdf6..b21162bc 100644 --- a/004-flutter-basics/05-view-model/pubspec.yaml +++ b/004-flutter-basics/05-view-model/pubspec.yaml @@ -1,66 +1,72 @@ -name: flutter_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: flutter_basics +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/004-flutter-basics/05-view-model/test/widget_test.dart b/004-flutter-basics/05-view-model/test/widget_test.dart index 026977f3..cd87292c 100644 --- a/004-flutter-basics/05-view-model/test/widget_test.dart +++ b/004-flutter-basics/05-view-model/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_basics/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/004-flutter-basics/README.md b/004-flutter-basics/README.md index 343791aa..2a1b98d7 100644 --- a/004-flutter-basics/README.md +++ b/004-flutter-basics/README.md @@ -1,5 +1,5 @@ -# Handling the basics in Flutter yourself - -In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. Understand how to implement simply and grow if needed. - -[Written tutorial](https://medium.com/@dane.mackier/flutter-foundation-going-from-setstate-to-architecture-handling-async-behaviour-925daf3bb8ec) +# Handling the basics in Flutter yourself + +In this tutorial we will go through the motions of handling the basics yourself without relying on an architecture. I've seen to many questions on StackOverflow about things that shouldn't be a question if you're using an architecture to build your apps. When you're using an architecture it should be a neccessity and because you've exausted the "pure" implementation. Understand how to implement simply and grow if needed. + +[Written tutorial](https://medium.com/@dane.mackier/flutter-foundation-going-from-setstate-to-architecture-handling-async-behaviour-925daf3bb8ec) diff --git a/005-basic-navigation/01-start/.gitignore b/005-basic-navigation/01-start/.gitignore index 5be59a14..07488ba6 100644 --- a/005-basic-navigation/01-start/.gitignore +++ b/005-basic-navigation/01-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/005-basic-navigation/01-start/.metadata b/005-basic-navigation/01-start/.metadata index 80977b64..8dcf6e4c 100644 --- a/005-basic-navigation/01-start/.metadata +++ b/005-basic-navigation/01-start/.metadata @@ -1,10 +1,10 @@ -# 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: 976223533d5fc5822b2fddca1652dac0037d16f2 - channel: master - -project_type: app +# 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: 976223533d5fc5822b2fddca1652dac0037d16f2 + channel: master + +project_type: app diff --git a/005-basic-navigation/01-start/README.md b/005-basic-navigation/01-start/README.md index d6ac3d07..5c0ef0e5 100644 --- a/005-basic-navigation/01-start/README.md +++ b/005-basic-navigation/01-start/README.md @@ -1,3 +1,3 @@ -# Flutter navigation guide using Navigator - +# Flutter navigation guide using Navigator + [Cheatsheet](https://medium.com/filledstacks/basic-navigation-in-flutter-navigator-only-cheatsheet-9c2e2584a6b1) \ No newline at end of file diff --git a/005-basic-navigation/01-start/android/app/build.gradle b/005-basic-navigation/01-start/android/app/build.gradle new file mode 100644 index 00000000..1644cbf3 --- /dev/null +++ b/005-basic-navigation/01-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.overflown" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/005-basic-navigation/01-start/android/app/src/debug/AndroidManifest.xml b/005-basic-navigation/01-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..8b226f36 --- /dev/null +++ b/005-basic-navigation/01-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/005-basic-navigation/01-start/android/app/src/main/AndroidManifest.xml b/005-basic-navigation/01-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..dc1bc607 --- /dev/null +++ b/005-basic-navigation/01-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/005-basic-navigation/01-start/android/app/src/main/java/com/example/overflown/MainActivity.java b/005-basic-navigation/01-start/android/app/src/main/java/com/example/overflown/MainActivity.java new file mode 100644 index 00000000..cedcd0e9 --- /dev/null +++ b/005-basic-navigation/01-start/android/app/src/main/java/com/example/overflown/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.overflown; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/005-basic-navigation/01-start/android/app/src/main/res/drawable/launch_background.xml b/005-basic-navigation/01-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/005-basic-navigation/01-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/005-basic-navigation/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/005-basic-navigation/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/005-basic-navigation/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/005-basic-navigation/01-start/android/app/src/main/res/values/styles.xml b/005-basic-navigation/01-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/005-basic-navigation/01-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/005-basic-navigation/01-start/android/app/src/profile/AndroidManifest.xml b/005-basic-navigation/01-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..8b226f36 --- /dev/null +++ b/005-basic-navigation/01-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/005-basic-navigation/01-start/android/build.gradle b/005-basic-navigation/01-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/005-basic-navigation/01-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/005-basic-navigation/01-start/android/gradle.properties b/005-basic-navigation/01-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/005-basic-navigation/01-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/005-basic-navigation/01-start/android/gradle/wrapper/gradle-wrapper.properties b/005-basic-navigation/01-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/005-basic-navigation/01-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/005-basic-navigation/01-start/android/settings.gradle b/005-basic-navigation/01-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/005-basic-navigation/01-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/005-basic-navigation/01-start/ios/Flutter/AppFrameworkInfo.plist b/005-basic-navigation/01-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/005-basic-navigation/01-start/ios/Flutter/Debug.xcconfig b/005-basic-navigation/01-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/005-basic-navigation/01-start/ios/Flutter/Release.xcconfig b/005-basic-navigation/01-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/005-basic-navigation/01-start/ios/Runner.xcodeproj/project.pbxproj b/005-basic-navigation/01-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..4b957814 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.overflown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.overflown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.overflown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/005-basic-navigation/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/005-basic-navigation/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/005-basic-navigation/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/005-basic-navigation/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/005-basic-navigation/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/005-basic-navigation/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/005-basic-navigation/01-start/ios/Runner/AppDelegate.h b/005-basic-navigation/01-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/005-basic-navigation/01-start/ios/Runner/AppDelegate.m b/005-basic-navigation/01-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/005-basic-navigation/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/005-basic-navigation/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/005-basic-navigation/01-start/ios/Runner/Base.lproj/Main.storyboard b/005-basic-navigation/01-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/005-basic-navigation/01-start/ios/Runner/Info.plist b/005-basic-navigation/01-start/ios/Runner/Info.plist new file mode 100644 index 00000000..329295f9 --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + overflown + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/005-basic-navigation/01-start/ios/Runner/main.m b/005-basic-navigation/01-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/005-basic-navigation/01-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/005-basic-navigation/01-start/lib/main.dart b/005-basic-navigation/01-start/lib/main.dart index 3e8555b6..c829418a 100644 --- a/005-basic-navigation/01-start/lib/main.dart +++ b/005-basic-navigation/01-start/lib/main.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; -import 'package:overflown/page1.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Page1(), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:overflown/page1.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Page1(), + ); + } +} diff --git a/005-basic-navigation/01-start/lib/page1.dart b/005-basic-navigation/01-start/lib/page1.dart index 190b06e4..1f4b110a 100644 --- a/005-basic-navigation/01-start/lib/page1.dart +++ b/005-basic-navigation/01-start/lib/page1.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; - -class Page1 extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - child: Center( - child: Text( - 'Page 1', - style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold), - ), - ), - ), - ); - } -} +import 'package:flutter/material.dart'; + +class Page1 extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + child: Center( + child: Text( + 'Page 1', + style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold), + ), + ), + ), + ); + } +} diff --git a/005-basic-navigation/01-start/lib/page2.dart b/005-basic-navigation/01-start/lib/page2.dart index 658a13a5..f88c1914 100644 --- a/005-basic-navigation/01-start/lib/page2.dart +++ b/005-basic-navigation/01-start/lib/page2.dart @@ -1,15 +1,15 @@ -import 'package:flutter/material.dart'; - -class Page2 extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - body: Container( - child: Center( - child: Text('Page 2', - style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold)), - ), - ), - ); - } -} +import 'package:flutter/material.dart'; + +class Page2 extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + child: Center( + child: Text('Page 2', + style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold)), + ), + ), + ); + } +} diff --git a/005-basic-navigation/01-start/pubspec.lock b/005-basic-navigation/01-start/pubspec.lock index 066a096b..f6b0bbdc 100644 --- a/005-basic-navigation/01-start/pubspec.lock +++ b/005-basic-navigation/01-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.1.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -113,7 +113,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.4" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/005-basic-navigation/01-start/pubspec.yaml b/005-basic-navigation/01-start/pubspec.yaml index 3141dab3..b964d61f 100644 --- a/005-basic-navigation/01-start/pubspec.yaml +++ b/005-basic-navigation/01-start/pubspec.yaml @@ -1,66 +1,72 @@ -name: overflown -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: overflown +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/005-basic-navigation/01-start/test/widget_test.dart b/005-basic-navigation/01-start/test/widget_test.dart index f8d4baa5..29bc586e 100644 --- a/005-basic-navigation/01-start/test/widget_test.dart +++ b/005-basic-navigation/01-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:overflown/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:overflown/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/005-basic-navigation/02-final/.gitignore b/005-basic-navigation/02-final/.gitignore index 5be59a14..07488ba6 100644 --- a/005-basic-navigation/02-final/.gitignore +++ b/005-basic-navigation/02-final/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/005-basic-navigation/02-final/.metadata b/005-basic-navigation/02-final/.metadata index 80977b64..8dcf6e4c 100644 --- a/005-basic-navigation/02-final/.metadata +++ b/005-basic-navigation/02-final/.metadata @@ -1,10 +1,10 @@ -# 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: 976223533d5fc5822b2fddca1652dac0037d16f2 - channel: master - -project_type: app +# 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: 976223533d5fc5822b2fddca1652dac0037d16f2 + channel: master + +project_type: app diff --git a/005-basic-navigation/02-final/README.md b/005-basic-navigation/02-final/README.md index d6ac3d07..5c0ef0e5 100644 --- a/005-basic-navigation/02-final/README.md +++ b/005-basic-navigation/02-final/README.md @@ -1,3 +1,3 @@ -# Flutter navigation guide using Navigator - +# Flutter navigation guide using Navigator + [Cheatsheet](https://medium.com/filledstacks/basic-navigation-in-flutter-navigator-only-cheatsheet-9c2e2584a6b1) \ No newline at end of file diff --git a/005-basic-navigation/02-final/android/app/build.gradle b/005-basic-navigation/02-final/android/app/build.gradle new file mode 100644 index 00000000..1644cbf3 --- /dev/null +++ b/005-basic-navigation/02-final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.overflown" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/005-basic-navigation/02-final/android/app/src/debug/AndroidManifest.xml b/005-basic-navigation/02-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..8b226f36 --- /dev/null +++ b/005-basic-navigation/02-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/005-basic-navigation/02-final/android/app/src/main/AndroidManifest.xml b/005-basic-navigation/02-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..dc1bc607 --- /dev/null +++ b/005-basic-navigation/02-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/005-basic-navigation/02-final/android/app/src/main/java/com/example/overflown/MainActivity.java b/005-basic-navigation/02-final/android/app/src/main/java/com/example/overflown/MainActivity.java new file mode 100644 index 00000000..cedcd0e9 --- /dev/null +++ b/005-basic-navigation/02-final/android/app/src/main/java/com/example/overflown/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.overflown; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/005-basic-navigation/02-final/android/app/src/main/res/drawable/launch_background.xml b/005-basic-navigation/02-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/005-basic-navigation/02-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/005-basic-navigation/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/005-basic-navigation/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/005-basic-navigation/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/005-basic-navigation/02-final/android/app/src/main/res/values/styles.xml b/005-basic-navigation/02-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/005-basic-navigation/02-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/005-basic-navigation/02-final/android/app/src/profile/AndroidManifest.xml b/005-basic-navigation/02-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..8b226f36 --- /dev/null +++ b/005-basic-navigation/02-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/005-basic-navigation/02-final/android/build.gradle b/005-basic-navigation/02-final/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/005-basic-navigation/02-final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/005-basic-navigation/02-final/android/gradle.properties b/005-basic-navigation/02-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/005-basic-navigation/02-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/005-basic-navigation/02-final/android/gradle/wrapper/gradle-wrapper.properties b/005-basic-navigation/02-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/005-basic-navigation/02-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/005-basic-navigation/02-final/android/settings.gradle b/005-basic-navigation/02-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/005-basic-navigation/02-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/005-basic-navigation/02-final/ios/Flutter/AppFrameworkInfo.plist b/005-basic-navigation/02-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/005-basic-navigation/02-final/ios/Flutter/Debug.xcconfig b/005-basic-navigation/02-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/005-basic-navigation/02-final/ios/Flutter/Release.xcconfig b/005-basic-navigation/02-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/005-basic-navigation/02-final/ios/Runner.xcodeproj/project.pbxproj b/005-basic-navigation/02-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..4b957814 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.overflown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.overflown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.overflown; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/005-basic-navigation/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/005-basic-navigation/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/005-basic-navigation/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/005-basic-navigation/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/005-basic-navigation/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/005-basic-navigation/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/005-basic-navigation/02-final/ios/Runner/AppDelegate.h b/005-basic-navigation/02-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/005-basic-navigation/02-final/ios/Runner/AppDelegate.m b/005-basic-navigation/02-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/005-basic-navigation/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/005-basic-navigation/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/005-basic-navigation/02-final/ios/Runner/Base.lproj/Main.storyboard b/005-basic-navigation/02-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/005-basic-navigation/02-final/ios/Runner/Info.plist b/005-basic-navigation/02-final/ios/Runner/Info.plist new file mode 100644 index 00000000..329295f9 --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + overflown + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/005-basic-navigation/02-final/ios/Runner/main.m b/005-basic-navigation/02-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/005-basic-navigation/02-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/005-basic-navigation/02-final/lib/main.dart b/005-basic-navigation/02-final/lib/main.dart index 3e8555b6..c829418a 100644 --- a/005-basic-navigation/02-final/lib/main.dart +++ b/005-basic-navigation/02-final/lib/main.dart @@ -1,17 +1,17 @@ -import 'package:flutter/material.dart'; -import 'package:overflown/page1.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Page1(), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:overflown/page1.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Page1(), + ); + } +} diff --git a/005-basic-navigation/02-final/lib/page1.dart b/005-basic-navigation/02-final/lib/page1.dart index 928cfbb4..a5fe569f 100644 --- a/005-basic-navigation/02-final/lib/page1.dart +++ b/005-basic-navigation/02-final/lib/page1.dart @@ -1,38 +1,38 @@ -import 'package:flutter/material.dart'; -import 'package:overflown/page2.dart'; - -class Page1 extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - floatingActionButton: FloatingActionButton( - onPressed: () async { - var navigationResult = await Navigator.push( - context, new MaterialPageRoute(builder: (context) => Page2())); - - if (navigationResult == 'from_back') { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text('Navigation from back'), - )); - } else if (navigationResult == 'from_button') { - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text('Navigation from button'), - )); - } - }, - ), - body: Container( - child: Center( - child: Text( - 'Page 1', - style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold), - ), - ), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:overflown/page2.dart'; + +class Page1 extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + floatingActionButton: FloatingActionButton( + onPressed: () async { + var navigationResult = await Navigator.push( + context, new MaterialPageRoute(builder: (context) => Page2())); + + if (navigationResult == 'from_back') { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Navigation from back'), + )); + } else if (navigationResult == 'from_button') { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Navigation from button'), + )); + } + }, + ), + body: Container( + child: Center( + child: Text( + 'Page 1', + style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold), + ), + ), + ), + ); + } +} diff --git a/005-basic-navigation/02-final/lib/page2.dart b/005-basic-navigation/02-final/lib/page2.dart index a3261536..daceeb7d 100644 --- a/005-basic-navigation/02-final/lib/page2.dart +++ b/005-basic-navigation/02-final/lib/page2.dart @@ -1,30 +1,30 @@ -import 'package:flutter/material.dart'; - -class Page2 extends StatelessWidget { - @override - Widget build(BuildContext context) { - return WillPopScope( - onWillPop: ()async { - _popNavigationWithResult(context, 'from_back'); - return false; - }, - child: Scaffold( - floatingActionButton: FloatingActionButton( - onPressed: () { - _popNavigationWithResult(context, 'from_button'); - }, - ), - body: Container( - child: Center( - child: Text('Page 2', - style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold)), - ), - ), - ), - ); - } - - void _popNavigationWithResult(BuildContext context, dynamic result) { - Navigator.pop(context, result); - } -} +import 'package:flutter/material.dart'; + +class Page2 extends StatelessWidget { + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: ()async { + _popNavigationWithResult(context, 'from_back'); + return false; + }, + child: Scaffold( + floatingActionButton: FloatingActionButton( + onPressed: () { + _popNavigationWithResult(context, 'from_button'); + }, + ), + body: Container( + child: Center( + child: Text('Page 2', + style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold)), + ), + ), + ), + ); + } + + void _popNavigationWithResult(BuildContext context, dynamic result) { + Navigator.pop(context, result); + } +} diff --git a/005-basic-navigation/02-final/pubspec.lock b/005-basic-navigation/02-final/pubspec.lock index 066a096b..f6b0bbdc 100644 --- a/005-basic-navigation/02-final/pubspec.lock +++ b/005-basic-navigation/02-final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.1.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -113,7 +113,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.4" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/005-basic-navigation/02-final/pubspec.yaml b/005-basic-navigation/02-final/pubspec.yaml index 3141dab3..b964d61f 100644 --- a/005-basic-navigation/02-final/pubspec.yaml +++ b/005-basic-navigation/02-final/pubspec.yaml @@ -1,66 +1,72 @@ -name: overflown -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: overflown +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/005-basic-navigation/02-final/test/widget_test.dart b/005-basic-navigation/02-final/test/widget_test.dart index f8d4baa5..29bc586e 100644 --- a/005-basic-navigation/02-final/test/widget_test.dart +++ b/005-basic-navigation/02-final/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:overflown/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:overflown/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/006-flare-drawer/01-start/.gitignore b/006-flare-drawer/01-start/.gitignore index 5be59a14..07488ba6 100644 --- a/006-flare-drawer/01-start/.gitignore +++ b/006-flare-drawer/01-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/006-flare-drawer/01-start/.metadata b/006-flare-drawer/01-start/.metadata index 63395157..362b4f81 100644 --- a/006-flare-drawer/01-start/.metadata +++ b/006-flare-drawer/01-start/.metadata @@ -1,10 +1,10 @@ -# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f - channel: master - -project_type: app +# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f + channel: master + +project_type: app diff --git a/006-flare-drawer/01-start/README.md b/006-flare-drawer/01-start/README.md index 35333ac2..dbd14725 100644 --- a/006-flare-drawer/01-start/README.md +++ b/006-flare-drawer/01-start/README.md @@ -1,3 +1,3 @@ -# Flutter Gooey slideout menu using Flutter - +# Flutter Gooey slideout menu using Flutter + This is the source code for the Tutorial that shows how to build a a Slideout menu in Flare. Then using [SmartFlare](https://pub.dartlang.org/packages/smart_flare) to add some interactive functionality to it. \ No newline at end of file diff --git a/006-flare-drawer/01-start/android/app/build.gradle b/006-flare-drawer/01-start/android/app/build.gradle new file mode 100644 index 00000000..6935ea34 --- /dev/null +++ b/006-flare-drawer/01-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flare_drawer" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/006-flare-drawer/01-start/android/app/src/debug/AndroidManifest.xml b/006-flare-drawer/01-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..ee13d06f --- /dev/null +++ b/006-flare-drawer/01-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/006-flare-drawer/01-start/android/app/src/main/AndroidManifest.xml b/006-flare-drawer/01-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a98916b2 --- /dev/null +++ b/006-flare-drawer/01-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/006-flare-drawer/01-start/android/app/src/main/java/com/example/flare_drawer/MainActivity.java b/006-flare-drawer/01-start/android/app/src/main/java/com/example/flare_drawer/MainActivity.java new file mode 100644 index 00000000..745eb954 --- /dev/null +++ b/006-flare-drawer/01-start/android/app/src/main/java/com/example/flare_drawer/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flare_drawer; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/006-flare-drawer/01-start/android/app/src/main/res/drawable/launch_background.xml b/006-flare-drawer/01-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/006-flare-drawer/01-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/006-flare-drawer/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/006-flare-drawer/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/006-flare-drawer/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/006-flare-drawer/01-start/android/app/src/main/res/values/styles.xml b/006-flare-drawer/01-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/006-flare-drawer/01-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/006-flare-drawer/01-start/android/app/src/profile/AndroidManifest.xml b/006-flare-drawer/01-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..ee13d06f --- /dev/null +++ b/006-flare-drawer/01-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/006-flare-drawer/01-start/android/build.gradle b/006-flare-drawer/01-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/006-flare-drawer/01-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/006-flare-drawer/01-start/android/gradle.properties b/006-flare-drawer/01-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/006-flare-drawer/01-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/006-flare-drawer/01-start/android/gradle/wrapper/gradle-wrapper.properties b/006-flare-drawer/01-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/006-flare-drawer/01-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/006-flare-drawer/01-start/android/settings.gradle b/006-flare-drawer/01-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/006-flare-drawer/01-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/006-flare-drawer/01-start/ios/Flutter/AppFrameworkInfo.plist b/006-flare-drawer/01-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/006-flare-drawer/01-start/ios/Flutter/Debug.xcconfig b/006-flare-drawer/01-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/006-flare-drawer/01-start/ios/Flutter/Release.xcconfig b/006-flare-drawer/01-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/006-flare-drawer/01-start/ios/Runner.xcodeproj/project.pbxproj b/006-flare-drawer/01-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..9a727109 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareDrawer; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareDrawer; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareDrawer; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/006-flare-drawer/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/006-flare-drawer/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/006-flare-drawer/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/006-flare-drawer/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/006-flare-drawer/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/006-flare-drawer/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/006-flare-drawer/01-start/ios/Runner/AppDelegate.h b/006-flare-drawer/01-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/006-flare-drawer/01-start/ios/Runner/AppDelegate.m b/006-flare-drawer/01-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/006-flare-drawer/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/006-flare-drawer/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/006-flare-drawer/01-start/ios/Runner/Base.lproj/Main.storyboard b/006-flare-drawer/01-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/006-flare-drawer/01-start/ios/Runner/Info.plist b/006-flare-drawer/01-start/ios/Runner/Info.plist new file mode 100644 index 00000000..dc2185ea --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flare_drawer + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/006-flare-drawer/01-start/ios/Runner/main.m b/006-flare-drawer/01-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/006-flare-drawer/01-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/006-flare-drawer/01-start/lib/main.dart b/006-flare-drawer/01-start/lib/main.dart index 1778eae6..1a5f81b8 100644 --- a/006-flare-drawer/01-start/lib/main.dart +++ b/006-flare-drawer/01-start/lib/main.dart @@ -1,27 +1,27 @@ -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Home() - ); - } -} - -class Home extends StatelessWidget { - @override - Widget build(BuildContext context) { - // TODO: implement build - return Scaffold( - body: Container(), - ); - } - +import 'package:flutter/material.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Home() + ); + } +} + +class Home extends StatelessWidget { + @override + Widget build(BuildContext context) { + // TODO: implement build + return Scaffold( + body: Container(), + ); + } + } \ No newline at end of file diff --git a/006-flare-drawer/01-start/pubspec.lock b/006-flare-drawer/01-start/pubspec.lock index 066a096b..f6b0bbdc 100644 --- a/006-flare-drawer/01-start/pubspec.lock +++ b/006-flare-drawer/01-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.1.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -113,7 +113,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.4" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/006-flare-drawer/01-start/pubspec.yaml b/006-flare-drawer/01-start/pubspec.yaml index af72dca6..ac7a324d 100644 --- a/006-flare-drawer/01-start/pubspec.yaml +++ b/006-flare-drawer/01-start/pubspec.yaml @@ -1,66 +1,72 @@ -name: flare_drawer -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: flare_drawer +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/006-flare-drawer/01-start/test/widget_test.dart b/006-flare-drawer/01-start/test/widget_test.dart index 10a0a57d..ebe1c478 100644 --- a/006-flare-drawer/01-start/test/widget_test.dart +++ b/006-flare-drawer/01-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flare_drawer/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flare_drawer/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/006-flare-drawer/02-final/.gitignore b/006-flare-drawer/02-final/.gitignore index 5be59a14..07488ba6 100644 --- a/006-flare-drawer/02-final/.gitignore +++ b/006-flare-drawer/02-final/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/006-flare-drawer/02-final/.metadata b/006-flare-drawer/02-final/.metadata index 63395157..362b4f81 100644 --- a/006-flare-drawer/02-final/.metadata +++ b/006-flare-drawer/02-final/.metadata @@ -1,10 +1,10 @@ -# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f - channel: master - -project_type: app +# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f + channel: master + +project_type: app diff --git a/006-flare-drawer/02-final/README.md b/006-flare-drawer/02-final/README.md index 35333ac2..dbd14725 100644 --- a/006-flare-drawer/02-final/README.md +++ b/006-flare-drawer/02-final/README.md @@ -1,3 +1,3 @@ -# Flutter Gooey slideout menu using Flutter - +# Flutter Gooey slideout menu using Flutter + This is the source code for the Tutorial that shows how to build a a Slideout menu in Flare. Then using [SmartFlare](https://pub.dartlang.org/packages/smart_flare) to add some interactive functionality to it. \ No newline at end of file diff --git a/006-flare-drawer/02-final/android/app/build.gradle b/006-flare-drawer/02-final/android/app/build.gradle new file mode 100644 index 00000000..6935ea34 --- /dev/null +++ b/006-flare-drawer/02-final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.flare_drawer" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/006-flare-drawer/02-final/android/app/src/debug/AndroidManifest.xml b/006-flare-drawer/02-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..ee13d06f --- /dev/null +++ b/006-flare-drawer/02-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/006-flare-drawer/02-final/android/app/src/main/AndroidManifest.xml b/006-flare-drawer/02-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a98916b2 --- /dev/null +++ b/006-flare-drawer/02-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/006-flare-drawer/02-final/android/app/src/main/java/com/example/flare_drawer/MainActivity.java b/006-flare-drawer/02-final/android/app/src/main/java/com/example/flare_drawer/MainActivity.java new file mode 100644 index 00000000..745eb954 --- /dev/null +++ b/006-flare-drawer/02-final/android/app/src/main/java/com/example/flare_drawer/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.flare_drawer; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/006-flare-drawer/02-final/android/app/src/main/res/drawable/launch_background.xml b/006-flare-drawer/02-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/006-flare-drawer/02-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/006-flare-drawer/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/006-flare-drawer/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/006-flare-drawer/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/006-flare-drawer/02-final/android/app/src/main/res/values/styles.xml b/006-flare-drawer/02-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/006-flare-drawer/02-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/006-flare-drawer/02-final/android/app/src/profile/AndroidManifest.xml b/006-flare-drawer/02-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..ee13d06f --- /dev/null +++ b/006-flare-drawer/02-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/006-flare-drawer/02-final/android/build.gradle b/006-flare-drawer/02-final/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/006-flare-drawer/02-final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/006-flare-drawer/02-final/android/gradle.properties b/006-flare-drawer/02-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/006-flare-drawer/02-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/006-flare-drawer/02-final/android/gradle/wrapper/gradle-wrapper.properties b/006-flare-drawer/02-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/006-flare-drawer/02-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/006-flare-drawer/02-final/android/settings.gradle b/006-flare-drawer/02-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/006-flare-drawer/02-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/006-flare-drawer/02-final/ios/Flutter/AppFrameworkInfo.plist b/006-flare-drawer/02-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/006-flare-drawer/02-final/ios/Flutter/Debug.xcconfig b/006-flare-drawer/02-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/006-flare-drawer/02-final/ios/Flutter/Release.xcconfig b/006-flare-drawer/02-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/006-flare-drawer/02-final/ios/Runner.xcodeproj/project.pbxproj b/006-flare-drawer/02-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..9a727109 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareDrawer; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareDrawer; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flareDrawer; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/006-flare-drawer/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/006-flare-drawer/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/006-flare-drawer/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/006-flare-drawer/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/006-flare-drawer/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/006-flare-drawer/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/006-flare-drawer/02-final/ios/Runner/AppDelegate.h b/006-flare-drawer/02-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/006-flare-drawer/02-final/ios/Runner/AppDelegate.m b/006-flare-drawer/02-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/006-flare-drawer/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/006-flare-drawer/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/006-flare-drawer/02-final/ios/Runner/Base.lproj/Main.storyboard b/006-flare-drawer/02-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/006-flare-drawer/02-final/ios/Runner/Info.plist b/006-flare-drawer/02-final/ios/Runner/Info.plist new file mode 100644 index 00000000..dc2185ea --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flare_drawer + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/006-flare-drawer/02-final/ios/Runner/main.m b/006-flare-drawer/02-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/006-flare-drawer/02-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/006-flare-drawer/02-final/lib/main.dart b/006-flare-drawer/02-final/lib/main.dart index a946d863..4c1d5c06 100644 --- a/006-flare-drawer/02-final/lib/main.dart +++ b/006-flare-drawer/02-final/lib/main.dart @@ -1,48 +1,48 @@ -import 'package:flutter/material.dart'; -import 'package:smart_flare/smart_flare.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Home()); - } -} - -class Home extends StatelessWidget { - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Scaffold( - backgroundColor: Colors.grey[700], - body: Container( - child: Align( - alignment: Alignment.centerRight, - child: PanFlareActor( - width: 135.0, - height: screenSize.height, - filename: 'assets/slideout-menu.flr', - openAnimation: 'open', - closeAnimation: 'close', - direction: ActorAdvancingDirection.RightToLeft, - threshold: 20.0, - reverseOnRelease: - true, // reverse's current animation when released and threshold not reaced - completeOnThresholdReached: - true, // plays the animation till the end when we reach threshold - activeAreas: [ - RelativePanArea( - area: Rect.fromLTWH(0, 0.7, 1.0, 0.3), debugArea: false) - ], - ), - ), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:smart_flare/smart_flare.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Home()); + } +} + +class Home extends StatelessWidget { + @override + Widget build(BuildContext context) { + var screenSize = MediaQuery.of(context).size; + return Scaffold( + backgroundColor: Colors.grey[700], + body: Container( + child: Align( + alignment: Alignment.centerRight, + child: PanFlareActor( + width: 135.0, + height: screenSize.height, + filename: 'assets/slideout-menu.flr', + openAnimation: 'open', + closeAnimation: 'close', + direction: ActorAdvancingDirection.RightToLeft, + threshold: 20.0, + reverseOnRelease: + true, // reverse's current animation when released and threshold not reaced + completeOnThresholdReached: + true, // plays the animation till the end when we reach threshold + activeAreas: [ + RelativePanArea( + area: Rect.fromLTWH(0, 0.7, 1.0, 0.3), debugArea: false) + ], + ), + ), + ), + ); + } +} diff --git a/006-flare-drawer/02-final/pubspec.lock b/006-flare-drawer/02-final/pubspec.lock index 79b7aadb..f93c5475 100644 --- a/006-flare-drawer/02-final/pubspec.lock +++ b/006-flare-drawer/02-final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,63 +7,49 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.1.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flare_dart: dependency: transitive description: name: flare_dart url: "https://pub.dartlang.org" source: hosted - version: "2.3.4" + version: "1.3.6" flare_flutter: dependency: transitive description: name: flare_flutter url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "1.3.10" flutter: dependency: "direct main" description: flutter @@ -80,21 +66,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" sky_engine: dependency: transitive description: flutter @@ -106,14 +106,14 @@ packages: name: smart_flare url: "https://pub.dartlang.org" source: hosted - version: "0.2.9+1" + version: "0.2.5" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -134,7 +134,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -148,7 +148,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.4" typed_data: dependency: transitive description: @@ -164,4 +164,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/006-flare-drawer/02-final/pubspec.yaml b/006-flare-drawer/02-final/pubspec.yaml index 7106572f..6e448fd2 100644 --- a/006-flare-drawer/02-final/pubspec.yaml +++ b/006-flare-drawer/02-final/pubspec.yaml @@ -1,68 +1,73 @@ -name: flare_drawer -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - smart_flare: ^0.2.9+1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/slideout-menu.flr - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: flare_drawer +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + smart_flare: ^0.2.5 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/slideout-menu.flr + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/006-flare-drawer/02-final/test/widget_test.dart b/006-flare-drawer/02-final/test/widget_test.dart index 10a0a57d..ebe1c478 100644 --- a/006-flare-drawer/02-final/test/widget_test.dart +++ b/006-flare-drawer/02-final/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flare_drawer/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flare_drawer/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/006-flare-drawer/README.txt b/006-flare-drawer/README.txt index 40be47cf..57ababcc 100644 --- a/006-flare-drawer/README.txt +++ b/006-flare-drawer/README.txt @@ -1,2 +1,2 @@ -DropBox assets link +DropBox assets link https://www.dropbox.com/s/8tt53n2yyo384h9/menu-assets.zip?dl=0 \ No newline at end of file diff --git a/007-scoped-model-guide/01-start/.gitignore b/007-scoped-model-guide/01-start/.gitignore index 5be59a14..07488ba6 100644 --- a/007-scoped-model-guide/01-start/.gitignore +++ b/007-scoped-model-guide/01-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/007-scoped-model-guide/01-start/.metadata b/007-scoped-model-guide/01-start/.metadata index 63395157..362b4f81 100644 --- a/007-scoped-model-guide/01-start/.metadata +++ b/007-scoped-model-guide/01-start/.metadata @@ -1,10 +1,10 @@ -# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f - channel: master - -project_type: app +# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f + channel: master + +project_type: app diff --git a/007-scoped-model-guide/01-start/README.md b/007-scoped-model-guide/01-start/README.md index 624a0e18..78ea4d71 100644 --- a/007-scoped-model-guide/01-start/README.md +++ b/007-scoped-model-guide/01-start/README.md @@ -1,16 +1,16 @@ -# scoped_guide - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +# scoped_guide + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/007-scoped-model-guide/01-start/android/app/build.gradle b/007-scoped-model-guide/01-start/android/app/build.gradle new file mode 100644 index 00000000..51645563 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.scoped_guide" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/007-scoped-model-guide/01-start/android/app/src/debug/AndroidManifest.xml b/007-scoped-model-guide/01-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..a45d19ff --- /dev/null +++ b/007-scoped-model-guide/01-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/007-scoped-model-guide/01-start/android/app/src/main/AndroidManifest.xml b/007-scoped-model-guide/01-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..893b28c3 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/01-start/android/app/src/main/java/com/example/scoped_guide/MainActivity.java b/007-scoped-model-guide/01-start/android/app/src/main/java/com/example/scoped_guide/MainActivity.java new file mode 100644 index 00000000..b2b299e1 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/app/src/main/java/com/example/scoped_guide/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.scoped_guide; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/007-scoped-model-guide/01-start/android/app/src/main/res/drawable/launch_background.xml b/007-scoped-model-guide/01-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/007-scoped-model-guide/01-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/01-start/android/app/src/main/res/values/styles.xml b/007-scoped-model-guide/01-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/007-scoped-model-guide/01-start/android/app/src/profile/AndroidManifest.xml b/007-scoped-model-guide/01-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..a45d19ff --- /dev/null +++ b/007-scoped-model-guide/01-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/007-scoped-model-guide/01-start/android/build.gradle b/007-scoped-model-guide/01-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/007-scoped-model-guide/01-start/android/gradle.properties b/007-scoped-model-guide/01-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/007-scoped-model-guide/01-start/android/gradle/wrapper/gradle-wrapper.properties b/007-scoped-model-guide/01-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/007-scoped-model-guide/01-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/007-scoped-model-guide/01-start/android/settings.gradle b/007-scoped-model-guide/01-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/007-scoped-model-guide/01-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/007-scoped-model-guide/01-start/ios/Flutter/AppFrameworkInfo.plist b/007-scoped-model-guide/01-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/007-scoped-model-guide/01-start/ios/Flutter/Debug.xcconfig b/007-scoped-model-guide/01-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/007-scoped-model-guide/01-start/ios/Flutter/Release.xcconfig b/007-scoped-model-guide/01-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/project.pbxproj b/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..e5046f50 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.scopedGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.scopedGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.scopedGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/007-scoped-model-guide/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/007-scoped-model-guide/01-start/ios/Runner/AppDelegate.h b/007-scoped-model-guide/01-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/007-scoped-model-guide/01-start/ios/Runner/AppDelegate.m b/007-scoped-model-guide/01-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/007-scoped-model-guide/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/007-scoped-model-guide/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/01-start/ios/Runner/Base.lproj/Main.storyboard b/007-scoped-model-guide/01-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/01-start/ios/Runner/Info.plist b/007-scoped-model-guide/01-start/ios/Runner/Info.plist new file mode 100644 index 00000000..338b6bc4 --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + scoped_guide + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/007-scoped-model-guide/01-start/ios/Runner/main.m b/007-scoped-model-guide/01-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/007-scoped-model-guide/01-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/007-scoped-model-guide/01-start/lib/main.dart b/007-scoped-model-guide/01-start/lib/main.dart index a4bd5804..cb76441d 100644 --- a/007-scoped-model-guide/01-start/lib/main.dart +++ b/007-scoped-model-guide/01-start/lib/main.dart @@ -1,16 +1,16 @@ -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Container(), - ); - } +import 'package:flutter/material.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: Container(), + ); + } } \ No newline at end of file diff --git a/007-scoped-model-guide/01-start/pubspec.lock b/007-scoped-model-guide/01-start/pubspec.lock index 066a096b..f6b0bbdc 100644 --- a/007-scoped-model-guide/01-start/pubspec.lock +++ b/007-scoped-model-guide/01-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.1.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,21 +52,35 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" sky_engine: dependency: transitive description: flutter @@ -92,7 +92,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -113,7 +113,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.4" typed_data: dependency: transitive description: @@ -143,4 +143,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/007-scoped-model-guide/01-start/pubspec.yaml b/007-scoped-model-guide/01-start/pubspec.yaml index 56b9a531..4357ba7b 100644 --- a/007-scoped-model-guide/01-start/pubspec.yaml +++ b/007-scoped-model-guide/01-start/pubspec.yaml @@ -1,66 +1,72 @@ -name: scoped_guide -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: scoped_guide +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/007-scoped-model-guide/01-start/test/widget_test.dart b/007-scoped-model-guide/01-start/test/widget_test.dart index 9d54ba07..f7ac9005 100644 --- a/007-scoped-model-guide/01-start/test/widget_test.dart +++ b/007-scoped-model-guide/01-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:scoped_guide/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:scoped_guide/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/007-scoped-model-guide/02-final/.gitignore b/007-scoped-model-guide/02-final/.gitignore index 5be59a14..07488ba6 100644 --- a/007-scoped-model-guide/02-final/.gitignore +++ b/007-scoped-model-guide/02-final/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/007-scoped-model-guide/02-final/.metadata b/007-scoped-model-guide/02-final/.metadata index 63395157..362b4f81 100644 --- a/007-scoped-model-guide/02-final/.metadata +++ b/007-scoped-model-guide/02-final/.metadata @@ -1,10 +1,10 @@ -# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f - channel: master - -project_type: app +# 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: 421f16a6b9176abb4ab3e9b9d1353300aa51712f + channel: master + +project_type: app diff --git a/007-scoped-model-guide/02-final/README.md b/007-scoped-model-guide/02-final/README.md index 624a0e18..78ea4d71 100644 --- a/007-scoped-model-guide/02-final/README.md +++ b/007-scoped-model-guide/02-final/README.md @@ -1,16 +1,16 @@ -# scoped_guide - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +# scoped_guide + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/007-scoped-model-guide/02-final/android/app/build.gradle b/007-scoped-model-guide/02-final/android/app/build.gradle new file mode 100644 index 00000000..51645563 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.scoped_guide" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/007-scoped-model-guide/02-final/android/app/src/debug/AndroidManifest.xml b/007-scoped-model-guide/02-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..a45d19ff --- /dev/null +++ b/007-scoped-model-guide/02-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/007-scoped-model-guide/02-final/android/app/src/main/AndroidManifest.xml b/007-scoped-model-guide/02-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..893b28c3 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/02-final/android/app/src/main/java/com/example/scoped_guide/MainActivity.java b/007-scoped-model-guide/02-final/android/app/src/main/java/com/example/scoped_guide/MainActivity.java new file mode 100644 index 00000000..b2b299e1 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/app/src/main/java/com/example/scoped_guide/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.scoped_guide; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/007-scoped-model-guide/02-final/android/app/src/main/res/drawable/launch_background.xml b/007-scoped-model-guide/02-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/007-scoped-model-guide/02-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/007-scoped-model-guide/02-final/android/app/src/main/res/values/styles.xml b/007-scoped-model-guide/02-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/007-scoped-model-guide/02-final/android/app/src/profile/AndroidManifest.xml b/007-scoped-model-guide/02-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..a45d19ff --- /dev/null +++ b/007-scoped-model-guide/02-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/007-scoped-model-guide/02-final/android/build.gradle b/007-scoped-model-guide/02-final/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/007-scoped-model-guide/02-final/android/gradle.properties b/007-scoped-model-guide/02-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/007-scoped-model-guide/02-final/android/gradle/wrapper/gradle-wrapper.properties b/007-scoped-model-guide/02-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/007-scoped-model-guide/02-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/007-scoped-model-guide/02-final/android/settings.gradle b/007-scoped-model-guide/02-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/007-scoped-model-guide/02-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/007-scoped-model-guide/02-final/ios/Flutter/AppFrameworkInfo.plist b/007-scoped-model-guide/02-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/007-scoped-model-guide/02-final/ios/Flutter/Debug.xcconfig b/007-scoped-model-guide/02-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/007-scoped-model-guide/02-final/ios/Flutter/Release.xcconfig b/007-scoped-model-guide/02-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/project.pbxproj b/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..e5046f50 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.scopedGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.scopedGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.scopedGuide; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/007-scoped-model-guide/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/007-scoped-model-guide/02-final/ios/Runner/AppDelegate.h b/007-scoped-model-guide/02-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/007-scoped-model-guide/02-final/ios/Runner/AppDelegate.m b/007-scoped-model-guide/02-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/007-scoped-model-guide/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/007-scoped-model-guide/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/02-final/ios/Runner/Base.lproj/Main.storyboard b/007-scoped-model-guide/02-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/007-scoped-model-guide/02-final/ios/Runner/Info.plist b/007-scoped-model-guide/02-final/ios/Runner/Info.plist new file mode 100644 index 00000000..338b6bc4 --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + scoped_guide + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/007-scoped-model-guide/02-final/ios/Runner/main.m b/007-scoped-model-guide/02-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/007-scoped-model-guide/02-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/007-scoped-model-guide/02-final/lib/enums/view_state.dart b/007-scoped-model-guide/02-final/lib/enums/view_state.dart index 248bdc4f..9a394e96 100644 --- a/007-scoped-model-guide/02-final/lib/enums/view_state.dart +++ b/007-scoped-model-guide/02-final/lib/enums/view_state.dart @@ -1,7 +1,7 @@ -/// Represents a view's state from the ScopedModel -enum ViewState { - Idle, - Busy, - Retrieved, - Error +/// Represents a view's state from the ScopedModel +enum ViewState { + Idle, + Busy, + Retrieved, + Error } \ No newline at end of file diff --git a/007-scoped-model-guide/02-final/lib/main.dart b/007-scoped-model-guide/02-final/lib/main.dart index 28bf5b2b..f9398a14 100644 --- a/007-scoped-model-guide/02-final/lib/main.dart +++ b/007-scoped-model-guide/02-final/lib/main.dart @@ -1,22 +1,22 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_guide/ui/views/home_view.dart'; -import 'service_locator.dart'; - -void main() { - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView(), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_guide/ui/views/home_view.dart'; +import 'service_locator.dart'; + +void main() { + setupLocator(); + + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: HomeView(), + ); + } +} diff --git a/007-scoped-model-guide/02-final/lib/scoped_models/base_model.dart b/007-scoped-model-guide/02-final/lib/scoped_models/base_model.dart index b5a486ba..e7fda3f7 100644 --- a/007-scoped-model-guide/02-final/lib/scoped_models/base_model.dart +++ b/007-scoped-model-guide/02-final/lib/scoped_models/base_model.dart @@ -1,18 +1,18 @@ -import 'package:scoped_guide/enums/view_state.dart'; -import 'package:scoped_model/scoped_model.dart'; -export 'package:scoped_model/scoped_model.dart'; - -// Make sure state enum is accessible in all inherting models -export 'package:scoped_guide/enums/view_state.dart'; - -class BaseModel extends Model { - ViewState _state; - ViewState get state => _state; - - void setState(ViewState newState) { - _state = newState; - - // Notify listeners will only update listeners of state. - notifyListeners(); - } -} +import 'package:scoped_guide/enums/view_state.dart'; +import 'package:scoped_model/scoped_model.dart'; +export 'package:scoped_model/scoped_model.dart'; + +// Make sure state enum is accessible in all inherting models +export 'package:scoped_guide/enums/view_state.dart'; + +class BaseModel extends Model { + ViewState _state; + ViewState get state => _state; + + void setState(ViewState newState) { + _state = newState; + + // Notify listeners will only update listeners of state. + notifyListeners(); + } +} diff --git a/007-scoped-model-guide/02-final/lib/scoped_models/error_model.dart b/007-scoped-model-guide/02-final/lib/scoped_models/error_model.dart index 66a20f83..bbfdf749 100644 --- a/007-scoped-model-guide/02-final/lib/scoped_models/error_model.dart +++ b/007-scoped-model-guide/02-final/lib/scoped_models/error_model.dart @@ -1,4 +1,4 @@ -import 'package:scoped_model/scoped_model.dart'; - -class ErrorModel extends Model { +import 'package:scoped_model/scoped_model.dart'; + +class ErrorModel extends Model { } \ No newline at end of file diff --git a/007-scoped-model-guide/02-final/lib/scoped_models/home_model.dart b/007-scoped-model-guide/02-final/lib/scoped_models/home_model.dart index 2cec84df..0ef51844 100644 --- a/007-scoped-model-guide/02-final/lib/scoped_models/home_model.dart +++ b/007-scoped-model-guide/02-final/lib/scoped_models/home_model.dart @@ -1,24 +1,24 @@ -import 'package:scoped_guide/service_locator.dart'; -import 'package:scoped_guide/services/storage_service.dart'; -import 'package:scoped_guide/enums/view_state.dart'; - -import 'base_model.dart'; - -export 'package:scoped_guide/enums/view_state.dart'; - -class HomeModel extends BaseModel { - StorageService storageService = locator(); - - String title = "HomeModel"; - - Future saveData() async { - setState(ViewState.Busy); - title = "Saving Data"; - await storageService.saveData(); - title = "Data Saved"; - setState(ViewState.Retrieved); - - return true; - } - +import 'package:scoped_guide/service_locator.dart'; +import 'package:scoped_guide/services/storage_service.dart'; +import 'package:scoped_guide/enums/view_state.dart'; + +import 'base_model.dart'; + +export 'package:scoped_guide/enums/view_state.dart'; + +class HomeModel extends BaseModel { + StorageService storageService = locator(); + + String title = "HomeModel"; + + Future saveData() async { + setState(ViewState.Busy); + title = "Saving Data"; + await storageService.saveData(); + title = "Data Saved"; + setState(ViewState.Retrieved); + + return true; + } + } \ No newline at end of file diff --git a/007-scoped-model-guide/02-final/lib/scoped_models/success_model.dart b/007-scoped-model-guide/02-final/lib/scoped_models/success_model.dart index e919c134..48d61c49 100644 --- a/007-scoped-model-guide/02-final/lib/scoped_models/success_model.dart +++ b/007-scoped-model-guide/02-final/lib/scoped_models/success_model.dart @@ -1,13 +1,13 @@ -import 'package:scoped_guide/scoped_models/base_model.dart'; - -class SuccessModel extends BaseModel { - String title = "no text yet"; - - Future fetchDuplicatedText(String text) async { - setState(ViewState.Busy); - await Future.delayed(Duration(seconds: 2)); - title = '$text $text'; - - setState(ViewState.Retrieved); - } +import 'package:scoped_guide/scoped_models/base_model.dart'; + +class SuccessModel extends BaseModel { + String title = "no text yet"; + + Future fetchDuplicatedText(String text) async { + setState(ViewState.Busy); + await Future.delayed(Duration(seconds: 2)); + title = '$text $text'; + + setState(ViewState.Retrieved); + } } \ No newline at end of file diff --git a/007-scoped-model-guide/02-final/lib/service_locator.dart b/007-scoped-model-guide/02-final/lib/service_locator.dart index 790e5e71..bb3d078a 100644 --- a/007-scoped-model-guide/02-final/lib/service_locator.dart +++ b/007-scoped-model-guide/02-final/lib/service_locator.dart @@ -1,17 +1,17 @@ -import 'package:get_it/get_it.dart'; -import 'package:scoped_guide/scoped_models/error_model.dart'; -import 'package:scoped_guide/scoped_models/home_model.dart'; -import 'package:scoped_guide/scoped_models/success_model.dart'; -import 'package:scoped_guide/services/storage_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - // register services - locator.registerLazySingleton(() => StorageService()); - - // register models - locator.registerFactory(() => HomeModel()); - locator.registerFactory(() => ErrorModel()); - locator.registerFactory(() => SuccessModel()); -} +import 'package:get_it/get_it.dart'; +import 'package:scoped_guide/scoped_models/error_model.dart'; +import 'package:scoped_guide/scoped_models/home_model.dart'; +import 'package:scoped_guide/scoped_models/success_model.dart'; +import 'package:scoped_guide/services/storage_service.dart'; + +GetIt locator = GetIt(); + +void setupLocator() { + // register services + locator.registerLazySingleton(() => StorageService()); + + // register models + locator.registerFactory(() => HomeModel()); + locator.registerFactory(() => ErrorModel()); + locator.registerFactory(() => SuccessModel()); +} \ No newline at end of file diff --git a/007-scoped-model-guide/02-final/lib/services/storage_service.dart b/007-scoped-model-guide/02-final/lib/services/storage_service.dart index 7fadc1cf..86f4dcac 100644 --- a/007-scoped-model-guide/02-final/lib/services/storage_service.dart +++ b/007-scoped-model-guide/02-final/lib/services/storage_service.dart @@ -1,6 +1,6 @@ -class StorageService { - Future saveData() async { - await Future.delayed(Duration(seconds: 2)); - return true; - } +class StorageService { + Future saveData() async { + await Future.delayed(Duration(seconds: 2)); + return true; + } } \ No newline at end of file diff --git a/007-scoped-model-guide/02-final/lib/ui/views/_template_view.dart b/007-scoped-model-guide/02-final/lib/ui/views/_template_view.dart index 46d6ba9a..ab1ae394 100644 --- a/007-scoped-model-guide/02-final/lib/ui/views/_template_view.dart +++ b/007-scoped-model-guide/02-final/lib/ui/views/_template_view.dart @@ -1,14 +1,14 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_guide/scoped_models/home_model.dart'; - -import 'base_view.dart'; - -class Template extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, child, model) => Scaffold( - body: Center(child: Text(this.runtimeType.toString()),), - )); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_guide/scoped_models/home_model.dart'; + +import 'base_view.dart'; + +class Template extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, child, model) => Scaffold( + body: Center(child: Text(this.runtimeType.toString()),), + )); + } +} diff --git a/007-scoped-model-guide/02-final/lib/ui/views/base_view.dart b/007-scoped-model-guide/02-final/lib/ui/views/base_view.dart index 30dac4cd..6e3b9edd 100644 --- a/007-scoped-model-guide/02-final/lib/ui/views/base_view.dart +++ b/007-scoped-model-guide/02-final/lib/ui/views/base_view.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_model/scoped_model.dart'; -import 'package:scoped_guide/service_locator.dart'; - -class BaseView extends StatefulWidget { - final ScopedModelDescendantBuilder _builder; - final Function(T) onModelReady; - - BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) - : _builder = builder; - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T _model = locator(); - - @override - void initState() { - if(widget.onModelReady != null) { - widget.onModelReady(_model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ScopedModel( - model: _model, - child: ScopedModelDescendant( - child: Container(color: Colors.red), - builder: widget._builder)); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:scoped_guide/service_locator.dart'; + +class BaseView extends StatefulWidget { + final ScopedModelDescendantBuilder _builder; + final Function(T) onModelReady; + + BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) + : _builder = builder; + + @override + _BaseViewState createState() => _BaseViewState(); +} + +class _BaseViewState extends State> { + T _model = locator(); + + @override + void initState() { + if(widget.onModelReady != null) { + widget.onModelReady(_model); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ScopedModel( + model: _model, + child: ScopedModelDescendant( + child: Container(color: Colors.red), + builder: widget._builder)); + } +} diff --git a/007-scoped-model-guide/02-final/lib/ui/views/error_view.dart b/007-scoped-model-guide/02-final/lib/ui/views/error_view.dart index 5a5b8bec..b28983e2 100644 --- a/007-scoped-model-guide/02-final/lib/ui/views/error_view.dart +++ b/007-scoped-model-guide/02-final/lib/ui/views/error_view.dart @@ -1,14 +1,14 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_guide/scoped_models/error_model.dart'; - -import 'base_view.dart'; - -class ErrorView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, child, model) => Scaffold( - body: Center(child: Text(this.runtimeType.toString()),), - )); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_guide/scoped_models/error_model.dart'; + +import 'base_view.dart'; + +class ErrorView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, child, model) => Scaffold( + body: Center(child: Text(this.runtimeType.toString()),), + )); + } +} diff --git a/007-scoped-model-guide/02-final/lib/ui/views/home_view.dart b/007-scoped-model-guide/02-final/lib/ui/views/home_view.dart index 185d7011..a3c99d4e 100644 --- a/007-scoped-model-guide/02-final/lib/ui/views/home_view.dart +++ b/007-scoped-model-guide/02-final/lib/ui/views/home_view.dart @@ -1,50 +1,50 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_guide/scoped_models/home_model.dart'; -import 'package:scoped_guide/ui/views/error_view.dart'; -import 'package:scoped_guide/ui/views/success_view.dart'; -import 'package:scoped_guide/ui/widgets/busy_overlay.dart'; - -import 'base_view.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, child, model) => - BusyOverlay( - show: model.state == ViewState.Busy, - child: Scaffold( - floatingActionButton: FloatingActionButton( - onPressed: () async { - var whereToNavigate = await model.saveData(); - if (whereToNavigate) { - Navigator.push(context,MaterialPageRoute(builder: (context) => SuccessView(title: "Passed in from home"))); - } else { - Navigator.push(context, - MaterialPageRoute(builder: (context) => ErrorView())); - } - }, - ), - body: Center( - child: Column( - children: [ - _getStateUi(model.state), - Text(model.title), - ], - ), - ), - ), - ) - ); - } - - Widget _getStateUi(ViewState state) { - switch (state) { - case ViewState.Busy: - return CircularProgressIndicator(); - case ViewState.Retrieved: - default: - return Text('Done'); - } - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_guide/scoped_models/home_model.dart'; +import 'package:scoped_guide/ui/views/error_view.dart'; +import 'package:scoped_guide/ui/views/success_view.dart'; +import 'package:scoped_guide/ui/widgets/busy_overlay.dart'; + +import 'base_view.dart'; + +class HomeView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, child, model) => + BusyOverlay( + show: model.state == ViewState.Busy, + child: Scaffold( + floatingActionButton: FloatingActionButton( + onPressed: () async { + var whereToNavigate = await model.saveData(); + if (whereToNavigate) { + Navigator.push(context,MaterialPageRoute(builder: (context) => SuccessView(title: "Passed in from home"))); + } else { + Navigator.push(context, + MaterialPageRoute(builder: (context) => ErrorView())); + } + }, + ), + body: Center( + child: Column( + children: [ + _getStateUi(model.state), + Text(model.title), + ], + ), + ), + ), + ) + ); + } + + Widget _getStateUi(ViewState state) { + switch (state) { + case ViewState.Busy: + return CircularProgressIndicator(); + case ViewState.Retrieved: + default: + return Text('Done'); + } + } +} diff --git a/007-scoped-model-guide/02-final/lib/ui/views/success_view.dart b/007-scoped-model-guide/02-final/lib/ui/views/success_view.dart index 7b7433ca..bb4076fc 100644 --- a/007-scoped-model-guide/02-final/lib/ui/views/success_view.dart +++ b/007-scoped-model-guide/02-final/lib/ui/views/success_view.dart @@ -1,23 +1,24 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_guide/enums/view_state.dart'; -import 'package:scoped_guide/scoped_models/success_model.dart'; -import 'package:scoped_guide/ui/widgets/busy_overlay.dart'; - -import 'base_view.dart'; - -class SuccessView extends StatelessWidget { - final String title; - - SuccessView({this.title}); - - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.fetchDuplicatedText(title), - builder: (context, child, model) => BusyOverlay( - show: model.state == ViewState.Busy, - child: Scaffold( - body: Center(child: Text(model.title)), - ))); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_guide/enums/view_state.dart'; +import 'package:scoped_guide/scoped_models/success_model.dart'; +import 'package:scoped_guide/service_locator.dart'; +import 'package:scoped_guide/ui/widgets/busy_overlay.dart'; + +import 'base_view.dart'; + +class SuccessView extends StatelessWidget { + final String title; + + SuccessView({this.title}); + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.fetchDuplicatedText(title), + builder: (context, child, model) => BusyOverlay( + show: model.state == ViewState.Busy, + child: Scaffold( + body: Center(child: Text(model.title)), + ))); + } +} diff --git a/007-scoped-model-guide/02-final/lib/ui/widgets/busy_overlay.dart b/007-scoped-model-guide/02-final/lib/ui/widgets/busy_overlay.dart index ec9fe0cc..3e391e12 100644 --- a/007-scoped-model-guide/02-final/lib/ui/widgets/busy_overlay.dart +++ b/007-scoped-model-guide/02-final/lib/ui/widgets/busy_overlay.dart @@ -1,41 +1,41 @@ -import 'package:flutter/material.dart'; - -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} +import 'package:flutter/material.dart'; + +class BusyOverlay extends StatelessWidget { + final Widget child; + final String title; + final bool show; + + const BusyOverlay({this.child, + this.title = 'Please wait...', + this.show = false}); + + @override + Widget build(BuildContext context) { + var screenSize = MediaQuery.of(context).size; + return Material( + child: Stack(children: [ + child, + IgnorePointer( + child: Opacity( + opacity: show ? 1.0 : 0.0, + child: Container( + width: screenSize.width, + height: screenSize.height, + alignment: Alignment.center, + color: Color.fromARGB(100, 0, 0, 0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(), + Text(title, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + )), + ), + ])); + } +} diff --git a/007-scoped-model-guide/02-final/pubspec.lock b/007-scoped-model-guide/02-final/pubspec.lock index f50d253e..b78155f3 100644 --- a/007-scoped-model-guide/02-final/pubspec.lock +++ b/007-scoped-model-guide/02-final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.1.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,28 +52,42 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "1.0.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" scoped_model: dependency: "direct main" description: @@ -106,7 +106,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.4" typed_data: dependency: transitive description: @@ -157,4 +157,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/007-scoped-model-guide/02-final/pubspec.yaml b/007-scoped-model-guide/02-final/pubspec.yaml index 5408bd75..e54a4306 100644 --- a/007-scoped-model-guide/02-final/pubspec.yaml +++ b/007-scoped-model-guide/02-final/pubspec.yaml @@ -1,70 +1,77 @@ -name: scoped_guide -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # scoped model - scoped_model: ^1.0.1 - # dependency injection - get_it: ^4.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: scoped_guide +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + # scoped model + scoped_model: ^1.0.1 + # dependency injection + get_it: ^1.0.3 + + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/007-scoped-model-guide/02-final/test/widget_test.dart b/007-scoped-model-guide/02-final/test/widget_test.dart index 9d54ba07..f7ac9005 100644 --- a/007-scoped-model-guide/02-final/test/widget_test.dart +++ b/007-scoped-model-guide/02-final/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:scoped_guide/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:scoped_guide/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/008-realtime-stats-app-with-firebase/001-start/.gitignore b/008-realtime-stats-app-with-firebase/001-start/.gitignore index 5be59a14..07488ba6 100644 --- a/008-realtime-stats-app-with-firebase/001-start/.gitignore +++ b/008-realtime-stats-app-with-firebase/001-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/008-realtime-stats-app-with-firebase/001-start/.metadata b/008-realtime-stats-app-with-firebase/001-start/.metadata index 0012359c..32e51230 100644 --- a/008-realtime-stats-app-with-firebase/001-start/.metadata +++ b/008-realtime-stats-app-with-firebase/001-start/.metadata @@ -1,10 +1,10 @@ -# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app +# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff + channel: master + +project_type: app diff --git a/008-realtime-stats-app-with-firebase/001-start/README.md b/008-realtime-stats-app-with-firebase/001-start/README.md index 9b0e6f2b..e2a9cf07 100644 --- a/008-realtime-stats-app-with-firebase/001-start/README.md +++ b/008-realtime-stats-app-with-firebase/001-start/README.md @@ -1,82 +1,82 @@ -# Flutter using AppSkeletons - ScopedModel architecture - -This project has been generated with [AppSkeletons](https://www.appskeletons.com). - -This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. - -ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. - -### About this template - -There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. - -#### One AppModel with FeatureModel mixins -In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. - -**Pros:** - - State is managed in one place (and all the benefits of that). - - All functionality is Easily accessible from one model using inherited widget functionality. - - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. - -**Cons:** - - notifyListeners can have multiple bindings alive at any point. - - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. - - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. - -#### One Model per view - -**Pros:** - - View has it's own dedicated Model - - All state functionality and reduction for a view is contained in it's own Model - - Better logical and mental grouping (View + View's Model) - -**Cons:** - - More Models to be aware of and manage - - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) - - Harder to make use of Logic from other models (which should never happen anyway) - -I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. - -### The implementation - -This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. - -Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. - -## Getting Started - -1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. -2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio -3. Run application - -## Structure and placement - -The root folder is split into 4 sections, models, scoped_models, services and ui. - -### Models - -Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. - -### Scoped Models - -In this scoped_models folder you'll place all the models associated with your views. One per view. - -**Naming convention:** [viewname]_model.dart i.e. home_model.dart - -### Services - -This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. - -**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart - -### UI - -Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. - -**views/**: Contains the files for each of the views in your applications. - -Naming convention: [viewname]_view.dart - -## Conclusion - +# Flutter using AppSkeletons - ScopedModel architecture + +This project has been generated with [AppSkeletons](https://www.appskeletons.com). + +This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. + +ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. + +### About this template + +There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. + +#### One AppModel with FeatureModel mixins +In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. + +**Pros:** + - State is managed in one place (and all the benefits of that). + - All functionality is Easily accessible from one model using inherited widget functionality. + - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. + +**Cons:** + - notifyListeners can have multiple bindings alive at any point. + - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. + - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. + +#### One Model per view + +**Pros:** + - View has it's own dedicated Model + - All state functionality and reduction for a view is contained in it's own Model + - Better logical and mental grouping (View + View's Model) + +**Cons:** + - More Models to be aware of and manage + - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) + - Harder to make use of Logic from other models (which should never happen anyway) + +I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. + +### The implementation + +This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. + +Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. + +## Getting Started + +1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. +2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio +3. Run application + +## Structure and placement + +The root folder is split into 4 sections, models, scoped_models, services and ui. + +### Models + +Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. + +### Scoped Models + +In this scoped_models folder you'll place all the models associated with your views. One per view. + +**Naming convention:** [viewname]_model.dart i.e. home_model.dart + +### Services + +This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. + +**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart + +### UI + +Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. + +**views/**: Contains the files for each of the views in your applications. + +Naming convention: [viewname]_view.dart + +## Conclusion + There are many other things you can setup in your app all depending on your code style. I have a full video on my [Youtube channel](https://www.youtube.com/channel/UC2d0BYlqQCdF9lJfydl_02Q) describing how to setup this template from scratch. \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/build.gradle b/008-realtime-stats-app-with-firebase/001-start/android/app/build.gradle new file mode 100644 index 00000000..ce55b1a6 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.appskeletons.skeleton_watcher" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/debug/AndroidManifest.xml b/008-realtime-stats-app-with-firebase/001-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/AndroidManifest.xml b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..92f71cc8 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java new file mode 100644 index 00000000..6e695021 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java @@ -0,0 +1,13 @@ +package com.appskeletons.skeleton_watcher; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/drawable/launch_background.xml b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..219bdbfa --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..70cde7e6 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..34d76500 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..03ca164d Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..5cbbce61 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..3ce53d50 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/values/colors.xml b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..d88c48a0 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #1A1B1E + \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/values/styles.xml b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/android/app/src/profile/AndroidManifest.xml b/008-realtime-stats-app-with-firebase/001-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/android/build.gradle b/008-realtime-stats-app-with-firebase/001-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/008-realtime-stats-app-with-firebase/001-start/android/gradle.properties b/008-realtime-stats-app-with-firebase/001-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/008-realtime-stats-app-with-firebase/001-start/android/gradle/wrapper/gradle-wrapper.properties b/008-realtime-stats-app-with-firebase/001-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/008-realtime-stats-app-with-firebase/001-start/android/settings.gradle b/008-realtime-stats-app-with-firebase/001-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/AppFrameworkInfo.plist b/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/Debug.xcconfig b/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/Release.xcconfig b/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.pbxproj b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..8f843ba4 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..949b6789 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Original + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/AppDelegate.h b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/AppDelegate.m b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..5bba67f7 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..bcbf413f Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..85071a7f Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..74ca0555 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..c1ab6b62 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..645f3ea4 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..b9e95e26 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..35a779aa Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..8561e1d0 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a645edf5 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..04a5aeae Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..3010c219 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..e6be06ed Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..0e78dc08 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/Contents.json b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json new file mode 100644 index 00000000..4605c085 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..5888d89e --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Base.lproj/Main.storyboard b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Info.plist b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Info.plist new file mode 100644 index 00000000..fa2050a2 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + skeleton_watcher + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/008-realtime-stats-app-with-firebase/001-start/ios/Runner/main.m b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/008-realtime-stats-app-with-firebase/001-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/enums/view_state.dart b/008-realtime-stats-app-with-firebase/001-start/lib/enums/view_state.dart index 72c2d168..a68c220e 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/enums/view_state.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/enums/view_state.dart @@ -1,13 +1,13 @@ - -/// A value mapping the View UI to the state in the Model. -/// -/// This will contain all the possible states for any view, custom enums can be created for separate views if required -enum ViewState { - Idle, // When nothing is happening or just initialized - Busy, // Typically shows a loading indicator of some sorts - DataFetched, // Indicates that there's data available on the view - NoDataAvailable, // Indicates that data was fetched successfully but nothing is available - Error, // Indicates there's an error on the view - Success, // Successful action occurred - WaitingForInput // The starting state that a form view is in + +/// A value mapping the View UI to the state in the Model. +/// +/// This will contain all the possible states for any view, custom enums can be created for separate views if required +enum ViewState { + Idle, // When nothing is happening or just initialized + Busy, // Typically shows a loading indicator of some sorts + DataFetched, // Indicates that there's data available on the view + NoDataAvailable, // Indicates that data was fetched successfully but nothing is available + Error, // Indicates there's an error on the view + Success, // Successful action occurred + WaitingForInput // The starting state that a form view is in } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/main.dart b/008-realtime-stats-app-with-firebase/001-start/lib/main.dart index 9e431cfb..6e8e5f91 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/main.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/main.dart @@ -1,26 +1,26 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/views/home_view.dart'; -import './service_locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Skeleton Watcher', - theme: ThemeData( - primaryColor: Color.fromARGB(255, 9, 202, 172), - backgroundColor: Color.fromARGB(255, 26, 27, 30), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - bodyColor: Colors.white, - displayColor: Colors.white)), - home: HomeView()); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/views/home_view.dart'; +import './service_locator.dart'; + +void main() { + // Register all the models and services before the app starts + setupLocator(); + + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Skeleton Watcher', + theme: ThemeData( + primaryColor: Color.fromARGB(255, 9, 202, 172), + backgroundColor: Color.fromARGB(255, 26, 27, 30), + textTheme: Theme.of(context).textTheme.apply( + fontFamily: 'Open Sans', + bodyColor: Colors.white, + displayColor: Colors.white)), + home: HomeView()); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/models/list_item.dart b/008-realtime-stats-app-with-firebase/001-start/lib/models/list_item.dart index 726d08b3..f4e10ccd 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/models/list_item.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/models/list_item.dart @@ -1,6 +1,6 @@ -class ListItem { - final String title; - final String description; - - ListItem({this.title, this.description}); +class ListItem { + final String title; + final String description; + + ListItem({this.title, this.description}); } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/models/user.dart b/008-realtime-stats-app-with-firebase/001-start/lib/models/user.dart index 7b050e50..6beb5a25 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/models/user.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/models/user.dart @@ -1,14 +1,14 @@ -class User { - final String username; - final String email; - final String userId; - final String accessToken; - - User({this.username, this.email, this.userId, this.accessToken}); - - User.fromJson(Map data) - : username = data['username'], - email = data['email'], - userId = data['userId'], - accessToken = data['accessToken']; -} +class User { + final String username; + final String email; + final String userId; + final String accessToken; + + User({this.username, this.email, this.userId, this.accessToken}); + + User.fromJson(Map data) + : username = data['username'], + email = data['email'], + userId = data['userId'], + accessToken = data['accessToken']; +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/base_model.dart b/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/base_model.dart index c66dd850..edee34fa 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/base_model.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/base_model.dart @@ -1,17 +1,17 @@ -import 'package:scoped_model/scoped_model.dart'; - -import 'package:skeleton_watcher/enums/view_state.dart'; -// Make sure state enum is accessible in all inherting models -export 'package:skeleton_watcher/enums/view_state.dart'; - -class BaseModel extends Model { - ViewState _state = ViewState.Idle; - ViewState get state => _state; - - void setState(ViewState newState) { - _state = newState; - - // Notify listeners will only update listeners of state. - notifyListeners(); - } -} +import 'package:scoped_model/scoped_model.dart'; + +import 'package:skeleton_watcher/enums/view_state.dart'; +// Make sure state enum is accessible in all inherting models +export 'package:skeleton_watcher/enums/view_state.dart'; + +class BaseModel extends Model { + ViewState _state = ViewState.Idle; + ViewState get state => _state; + + void setState(ViewState newState) { + _state = newState; + + // Notify listeners will only update listeners of state. + notifyListeners(); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/feedback_view_model.dart b/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/feedback_view_model.dart index 3a9c6ff8..e1a79020 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/feedback_view_model.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/feedback_view_model.dart @@ -1,28 +1,27 @@ -import 'package:skeleton_watcher/models/list_item.dart'; -import 'base_model.dart'; - -export 'package:skeleton_watcher/enums/view_state.dart'; - -/// Contains logic for a list view with the general expected functionality. -class FeedbackViewModel extends BaseModel { - List listData; - - Future fetchListData() async { - setState(ViewState.Busy); - - await Future.delayed(Duration(seconds: 1)); - listData = List.generate( - 10, - (index) => ListItem( - title: 'title $index', - description: 'Description of this list Item. $index')); - - if (listData == null) { - setState(ViewState.Error); - } else { - setState(listData.length == 0 - ? ViewState.NoDataAvailable - : ViewState.DataFetched); - } - } -} +import 'package:scoped_model/scoped_model.dart'; +import 'package:skeleton_watcher/models/list_item.dart'; +import 'base_model.dart'; + +export 'package:skeleton_watcher/enums/view_state.dart'; + + +/// Contains logic for a list view with the general expected functionality. +class FeedbackViewModel extends BaseModel { + List listData; + + Future fetchListData() async { + setState(ViewState.Busy); + + await Future.delayed(Duration(seconds: 1)); + listData = List.generate(10, (index) => + ListItem(title: 'title $index', description: 'Description of this list Item. $index')); + + if (listData == null) { + setState(ViewState.Error); + } else { + setState(listData.length == 0 + ? ViewState.NoDataAvailable + : ViewState.DataFetched); + } + } +} \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/home_view_model.dart b/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/home_view_model.dart index f6a01509..7a40594e 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/home_view_model.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/scoped_models/home_view_model.dart @@ -1,3 +1,3 @@ -import 'base_model.dart'; -class HomeViewModel extends BaseModel { +import 'base_model.dart'; +class HomeViewModel extends BaseModel { } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/service_locator.dart b/008-realtime-stats-app-with-firebase/001-start/lib/service_locator.dart index f3930517..23d4256a 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/service_locator.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/service_locator.dart @@ -1,13 +1,14 @@ -import 'package:get_it/get_it.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - // Register services - - // Register ScopedModels - locator.registerFactory(() => HomeViewModel()); - locator.registerFactory(() => FeedbackViewModel()); -} +import 'package:get_it/get_it.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; + +GetIt locator = new GetIt(); + +void setupLocator() { + // Register services + + // Register ScopedModels + locator.registerFactory(() => HomeViewModel()); + locator.registerFactory(() => FeedbackViewModel()); +} + diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/app_colors.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/app_colors.dart index e5ca3a2c..d976c11e 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/app_colors.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/app_colors.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); +import 'package:flutter/material.dart'; + +const Color lightGrey = Color.fromARGB(255,61,63,69); +const Color darkGrey = Color.fromARGB(255,18,18,19); +const Color primaryColor = Color.fromARGB(255, 9, 202, 172); +const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/font_styles.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/font_styles.dart index d224f955..bed44618 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/font_styles.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/font_styles.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); const TextStyle viewErrorTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800, color: lightGrey); \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_helpers.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_helpers.dart index 8665bf7c..390780a6 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_helpers.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_helpers.dart @@ -1,114 +1,114 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 20.0; - static const double _VerticalSpaceMedium = 40.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 20.0; - static const double _HorizontalSpaceMedium = 40.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } - - /// Provides an input field with a title that stretches the full width of the screen - static Widget inputField({ - String title, - String placeholder, - @required TextEditingController controller, - String validationMessage, - bool isPassword = false, - double spaceBetweenTitle = 15.0, - double padding = 10.0}) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), - validationMessage != null ? Text( - validationMessage, - style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), - Container( - alignment: Alignment(0.0, 0.0), - padding: EdgeInsets.only(left: padding), - margin: EdgeInsets.only(top: spaceBetweenTitle), - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: lightGrey - ), - child: TextField( - controller: controller, - obscureText: isPassword, - style: TextStyle(fontSize: 12.0), - decoration: InputDecoration.collapsed( - hintText: placeholder, - hintStyle: - TextStyle(color: Colors.grey[600], fontSize: 12.0)), - ), - ) - ]); - } - - static Widget fullScreenButton({ - String title, - Function onTap - }) { - return GestureDetector( - onTap: onTap , - child: Container( - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Color.fromARGB(255, 9, 202, 172)), - child: Center( - child: - Text(title, style: TextStyle(fontWeight: FontWeight.w800))), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +/// Contains useful functions to reduce boilerplate code +class UIHelper { + // Vertical spacing constants. Adjust to your liking. + static const double _VerticalSpaceSmall = 20.0; + static const double _VerticalSpaceMedium = 40.0; + static const double _VerticalSpaceLarge = 60.0; + + // Vertical spacing constants. Adjust to your liking. + static const double _HorizontalSpaceSmall = 20.0; + static const double _HorizontalSpaceMedium = 40.0; + static const double HorizontalSpaceLarge = 60.0; + + /// Returns a vertical space with height set to [_VerticalSpaceSmall] + static Widget verticalSpaceSmall() { + return verticalSpace(_VerticalSpaceSmall); + } + + /// Returns a vertical space with height set to [_VerticalSpaceMedium] + static Widget verticalSpaceMedium() { + return verticalSpace(_VerticalSpaceMedium); + } + + /// Returns a vertical space with height set to [_VerticalSpaceLarge] + static Widget verticalSpaceLarge() { + return verticalSpace(_VerticalSpaceLarge); + } + + /// Returns a vertical space equal to the [height] supplied + static Widget verticalSpace(double height) { + return Container(height: height); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceSmall] + static Widget horizontalSpaceSmall() { + return horizontalSpace(_HorizontalSpaceSmall); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceMedium] + static Widget horizontalSpaceMedium() { + return horizontalSpace(_HorizontalSpaceMedium); + } + + /// Returns a vertical space with height set to [HorizontalSpaceLarge] + static Widget horizontalSpaceLarge() { + return horizontalSpace(HorizontalSpaceLarge); + } + + /// Returns a vertical space equal to the [width] supplied + static Widget horizontalSpace(double width) { + return Container(width: width); + } + + /// Provides an input field with a title that stretches the full width of the screen + static Widget inputField({ + String title, + String placeholder, + @required TextEditingController controller, + String validationMessage, + bool isPassword = false, + double spaceBetweenTitle = 15.0, + double padding = 10.0}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, + style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), + validationMessage != null ? Text( + validationMessage, + style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), + Container( + alignment: Alignment(0.0, 0.0), + padding: EdgeInsets.only(left: padding), + margin: EdgeInsets.only(top: spaceBetweenTitle), + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: lightGrey + ), + child: TextField( + controller: controller, + obscureText: isPassword, + style: TextStyle(fontSize: 12.0), + decoration: InputDecoration.collapsed( + hintText: placeholder, + hintStyle: + TextStyle(color: Colors.grey[600], fontSize: 12.0)), + ), + ) + ]); + } + + static Widget fullScreenButton({ + String title, + Function onTap + }) { + return GestureDetector( + onTap: onTap , + child: Container( + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: Color.fromARGB(255, 9, 202, 172)), + child: Center( + child: + Text(title, style: TextStyle(fontWeight: FontWeight.w800))), + ), + ); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_reducers.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_reducers.dart index 54c9c712..0e8b0fb4 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_reducers.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/shared/ui_reducers.dart @@ -1,7 +1,7 @@ -import 'package:flutter/widgets.dart'; - -double screenHeight(BuildContext context, - {int dividedBy = 1, double decreasedBy = 0.0}) { - assert(dividedBy != 0, "Don't divide by 0"); - return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; -} +import 'package:flutter/widgets.dart'; + +double screenHeight(BuildContext context, + {int dividedBy = 1, double decreasedBy = 0.0}) { + assert(dividedBy != 0, "Don't divide by 0"); + return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/base_view.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/base_view.dart index 042f5f47..dcda33b3 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/base_view.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/base_view.dart @@ -1,40 +1,40 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_model/scoped_model.dart'; -import 'package:skeleton_watcher/service_locator.dart'; - -class BaseView extends StatefulWidget { - - final ScopedModelDescendantBuilder _builder; - - /// Function will be called as soon as the widget is initialised. - /// - /// Callback will reive the model that was created and supplied to the ScopedModel - final Function(T) onModelReady; - - BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) - : _builder = builder; - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T _model = locator(); - - @override - void initState() { - if(widget.onModelReady != null) { - widget.onModelReady(_model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ScopedModel( - model: _model, - child: ScopedModelDescendant( - child: Container(color: Colors.red), - builder: widget._builder)); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:skeleton_watcher/service_locator.dart'; + +class BaseView extends StatefulWidget { + + final ScopedModelDescendantBuilder _builder; + + /// Function will be called as soon as the widget is initialised. + /// + /// Callback will reive the model that was created and supplied to the ScopedModel + final Function(T) onModelReady; + + BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) + : _builder = builder; + + @override + _BaseViewState createState() => _BaseViewState(); +} + +class _BaseViewState extends State> { + T _model = locator(); + + @override + void initState() { + if(widget.onModelReady != null) { + widget.onModelReady(_model); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ScopedModel( + model: _model, + child: ScopedModelDescendant( + child: Container(color: Colors.red), + builder: widget._builder)); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/feedback_view.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/feedback_view.dart index 8abadc60..d0660247 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/feedback_view.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/feedback_view.dart @@ -1,109 +1,109 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/models/list_item.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; -import 'package:skeleton_watcher/ui/shared/font_styles.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; - -class FeedbackView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.fetchListData(), - builder: (context, childe, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: Container(child: _getBodyUi(context, model)))); - } - - Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { - switch (model.state) { - case ViewState.Busy: - return _getLoadingUi(context); - case ViewState.NoDataAvailable: - return _noDataUi(context, model); - case ViewState.Error: - return _errorUi(context, model); - case ViewState.DataFetched: - default: - return _getListUi(model); - } - } - - Widget _getListUi(FeedbackViewModel model) { - return ListView.builder( - itemCount: model.listData.length, - itemBuilder: (context, itemIndex) { - var item = model.listData[itemIndex]; - return _getListItemUi(item); - }); - } - - Container _getListItemUi(ListItem result) { - return Container( - height: 100.0, - margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: lightGrey), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(result.title, style: viewTitle), - Text(result.description) - ], - ), - ); - } - - Widget _getLoadingUi(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator( - valueColor: - AlwaysStoppedAnimation(Theme.of(context).primaryColor)), - Text('Fetching data ...') - ], - )); - } - - Widget _noDataUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage( - context, - "No data available yet", - model); - } - - Widget _errorUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage( - context, - "Error retrieving your data. Tap to try again", - model, - error: true); - } - - Widget _getCenteredViewMessage( - BuildContext context, String message, FeedbackViewModel model, - {bool error = false}) { - return Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - message, - style: viewErrorTitle, - textAlign: TextAlign.center, - ), - error - ? Icon( // WWrap in gesture detector and call you refresh future here - Icons.refresh, - color: Colors.white, - size: 45.0, - ) - : Container() - ], - ))); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/models/list_item.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; +import 'package:skeleton_watcher/ui/shared/font_styles.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; + +class FeedbackView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.fetchListData(), + builder: (context, childe, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: Container(child: _getBodyUi(context, model)))); + } + + Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { + switch (model.state) { + case ViewState.Busy: + return _getLoadingUi(context); + case ViewState.NoDataAvailable: + return _noDataUi(context, model); + case ViewState.Error: + return _errorUi(context, model); + case ViewState.DataFetched: + default: + return _getListUi(model); + } + } + + Widget _getListUi(FeedbackViewModel model) { + return ListView.builder( + itemCount: model.listData.length, + itemBuilder: (context, itemIndex) { + var item = model.listData[itemIndex]; + return _getListItemUi(item); + }); + } + + Container _getListItemUi(ListItem result) { + return Container( + height: 100.0, + margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: lightGrey), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(result.title, style: viewTitle), + Text(result.description) + ], + ), + ); + } + + Widget _getLoadingUi(BuildContext context) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation(Theme.of(context).primaryColor)), + Text('Fetching data ...') + ], + )); + } + + Widget _noDataUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage( + context, + "No data available yet", + model); + } + + Widget _errorUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage( + context, + "Error retrieving your data. Tap to try again", + model, + error: true); + } + + Widget _getCenteredViewMessage( + BuildContext context, String message, FeedbackViewModel model, + {bool error = false}) { + return Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + message, + style: viewErrorTitle, + textAlign: TextAlign.center, + ), + error + ? Icon( // WWrap in gesture detector and call you refresh future here + Icons.refresh, + color: Colors.white, + size: 45.0, + ) + : Container() + ], + ))); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/home_view.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/home_view.dart index 80426004..de3e386a 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/home_view.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/views/home_view.dart @@ -1,18 +1,18 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, child, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: Container( - padding: EdgeInsets.only(left: 25.0, right: 25.0), - child: - Container() - ))); - } - +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; + +class HomeView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, child, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: Container( + padding: EdgeInsets.only(left: 25.0, right: 25.0), + child: + Container() + ))); + } + } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/001-start/lib/ui/widgets/busy_overlay.dart b/008-realtime-stats-app-with-firebase/001-start/lib/ui/widgets/busy_overlay.dart index 24f0f4b6..f2617207 100644 --- a/008-realtime-stats-app-with-firebase/001-start/lib/ui/widgets/busy_overlay.dart +++ b/008-realtime-stats-app-with-firebase/001-start/lib/ui/widgets/busy_overlay.dart @@ -1,45 +1,45 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} +import 'package:flutter/material.dart'; + +/// A modal overlay that will show over your child widget (fullscreen) when the show value is true +/// +/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when +/// your model state is Busy +class BusyOverlay extends StatelessWidget { + final Widget child; + final String title; + final bool show; + + const BusyOverlay({this.child, + this.title = 'Please wait...', + this.show = false}); + + @override + Widget build(BuildContext context) { + var screenSize = MediaQuery.of(context).size; + return Material( + child: Stack(children: [ + child, + IgnorePointer( + child: Opacity( + opacity: show ? 1.0 : 0.0, + child: Container( + width: screenSize.width, + height: screenSize.height, + alignment: Alignment.center, + color: Color.fromARGB(100, 0, 0, 0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(), + Text(title, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + )), + ), + ])); + } +} diff --git a/008-realtime-stats-app-with-firebase/001-start/pubspec.lock b/008-realtime-stats-app-with-firebase/001-start/pubspec.lock index f50d253e..32bfd39a 100644 --- a/008-realtime-stats-app-with-firebase/001-start/pubspec.lock +++ b/008-realtime-stats-app-with-firebase/001-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.2.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,28 +52,42 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "1.0.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" scoped_model: dependency: "direct main" description: @@ -106,7 +106,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -127,7 +127,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.5" typed_data: dependency: transitive description: @@ -157,4 +157,4 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" diff --git a/008-realtime-stats-app-with-firebase/001-start/pubspec.yaml b/008-realtime-stats-app-with-firebase/001-start/pubspec.yaml index 33aaae6e..bc7bde4b 100644 --- a/008-realtime-stats-app-with-firebase/001-start/pubspec.yaml +++ b/008-realtime-stats-app-with-firebase/001-start/pubspec.yaml @@ -1,74 +1,76 @@ -name: skeleton_watcher -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # scoped model packages - scoped_model: ^1.0.1 - # get it - get_it: ^4.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: skeleton_watcher +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + # scoped model packages + scoped_model: ^1.0.1 + # get it + get_it: ^1.0.3 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: Open Sans + fonts: + - asset: assets/fonts/OpenSans-Bold.ttf + weight: 700 + - asset: assets/fonts/OpenSans-ExtraBold.ttf + weight: 800 + - asset: assets/fonts/OpenSans-Light.ttf + weight: 300 + - asset: assets/fonts/OpenSans-Regular.ttf + weight: 400 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/008-realtime-stats-app-with-firebase/001-start/test/widget_test.dart b/008-realtime-stats-app-with-firebase/001-start/test/widget_test.dart index ee9c85de..688c5230 100644 --- a/008-realtime-stats-app-with-firebase/001-start/test/widget_test.dart +++ b/008-realtime-stats-app-with-firebase/001-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:skeleton_watcher/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:skeleton_watcher/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/008-realtime-stats-app-with-firebase/002-final/.flutter-plugins-dependencies b/008-realtime-stats-app-with-firebase/002-final/.flutter-plugins-dependencies deleted file mode 100644 index e294aa8e..00000000 --- a/008-realtime-stats-app-with-firebase/002-final/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.10.0/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.3.4/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.10.0/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.3.4/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core"]},{"name":"firebase_core","dependencies":[]}],"date_created":"2020-06-18 21:48:26.595283","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/.gitignore b/008-realtime-stats-app-with-firebase/002-final/.gitignore index 5be59a14..07488ba6 100644 --- a/008-realtime-stats-app-with-firebase/002-final/.gitignore +++ b/008-realtime-stats-app-with-firebase/002-final/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/008-realtime-stats-app-with-firebase/002-final/.metadata b/008-realtime-stats-app-with-firebase/002-final/.metadata index 0012359c..32e51230 100644 --- a/008-realtime-stats-app-with-firebase/002-final/.metadata +++ b/008-realtime-stats-app-with-firebase/002-final/.metadata @@ -1,10 +1,10 @@ -# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app +# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff + channel: master + +project_type: app diff --git a/008-realtime-stats-app-with-firebase/002-final/README.md b/008-realtime-stats-app-with-firebase/002-final/README.md index 9b0e6f2b..e2a9cf07 100644 --- a/008-realtime-stats-app-with-firebase/002-final/README.md +++ b/008-realtime-stats-app-with-firebase/002-final/README.md @@ -1,82 +1,82 @@ -# Flutter using AppSkeletons - ScopedModel architecture - -This project has been generated with [AppSkeletons](https://www.appskeletons.com). - -This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. - -ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. - -### About this template - -There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. - -#### One AppModel with FeatureModel mixins -In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. - -**Pros:** - - State is managed in one place (and all the benefits of that). - - All functionality is Easily accessible from one model using inherited widget functionality. - - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. - -**Cons:** - - notifyListeners can have multiple bindings alive at any point. - - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. - - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. - -#### One Model per view - -**Pros:** - - View has it's own dedicated Model - - All state functionality and reduction for a view is contained in it's own Model - - Better logical and mental grouping (View + View's Model) - -**Cons:** - - More Models to be aware of and manage - - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) - - Harder to make use of Logic from other models (which should never happen anyway) - -I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. - -### The implementation - -This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. - -Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. - -## Getting Started - -1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. -2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio -3. Run application - -## Structure and placement - -The root folder is split into 4 sections, models, scoped_models, services and ui. - -### Models - -Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. - -### Scoped Models - -In this scoped_models folder you'll place all the models associated with your views. One per view. - -**Naming convention:** [viewname]_model.dart i.e. home_model.dart - -### Services - -This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. - -**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart - -### UI - -Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. - -**views/**: Contains the files for each of the views in your applications. - -Naming convention: [viewname]_view.dart - -## Conclusion - +# Flutter using AppSkeletons - ScopedModel architecture + +This project has been generated with [AppSkeletons](https://www.appskeletons.com). + +This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. + +ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. + +### About this template + +There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. + +#### One AppModel with FeatureModel mixins +In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. + +**Pros:** + - State is managed in one place (and all the benefits of that). + - All functionality is Easily accessible from one model using inherited widget functionality. + - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. + +**Cons:** + - notifyListeners can have multiple bindings alive at any point. + - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. + - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. + +#### One Model per view + +**Pros:** + - View has it's own dedicated Model + - All state functionality and reduction for a view is contained in it's own Model + - Better logical and mental grouping (View + View's Model) + +**Cons:** + - More Models to be aware of and manage + - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) + - Harder to make use of Logic from other models (which should never happen anyway) + +I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. + +### The implementation + +This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. + +Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. + +## Getting Started + +1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. +2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio +3. Run application + +## Structure and placement + +The root folder is split into 4 sections, models, scoped_models, services and ui. + +### Models + +Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. + +### Scoped Models + +In this scoped_models folder you'll place all the models associated with your views. One per view. + +**Naming convention:** [viewname]_model.dart i.e. home_model.dart + +### Services + +This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. + +**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart + +### UI + +Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. + +**views/**: Contains the files for each of the views in your applications. + +Naming convention: [viewname]_view.dart + +## Conclusion + There are many other things you can setup in your app all depending on your code style. I have a full video on my [Youtube channel](https://www.youtube.com/channel/UC2d0BYlqQCdF9lJfydl_02Q) describing how to setup this template from scratch. \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/build.gradle b/008-realtime-stats-app-with-firebase/002-final/android/app/build.gradle new file mode 100644 index 00000000..0e1f6e02 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/build.gradle @@ -0,0 +1,66 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.appskeletons.skeleton_watcher" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + multiDexEnabled true + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'com.google.firebase:firebase-core:16.0.1' + implementation 'com.android.support:multidex:1.0.3' +} + +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/debug/AndroidManifest.xml b/008-realtime-stats-app-with-firebase/002-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/AndroidManifest.xml b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..92f71cc8 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java new file mode 100644 index 00000000..6e695021 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java @@ -0,0 +1,13 @@ +package com.appskeletons.skeleton_watcher; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/drawable/launch_background.xml b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..219bdbfa --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..70cde7e6 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..34d76500 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..03ca164d Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..5cbbce61 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..3ce53d50 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/values/colors.xml b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..d88c48a0 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #1A1B1E + \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/values/styles.xml b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/android/app/src/profile/AndroidManifest.xml b/008-realtime-stats-app-with-firebase/002-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/android/build.gradle b/008-realtime-stats-app-with-firebase/002-final/android/build.gradle new file mode 100644 index 00000000..3e107571 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/build.gradle @@ -0,0 +1,30 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.google.gms:google-services:4.0.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/008-realtime-stats-app-with-firebase/002-final/android/gradle.properties b/008-realtime-stats-app-with-firebase/002-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/008-realtime-stats-app-with-firebase/002-final/android/gradle/wrapper/gradle-wrapper.properties b/008-realtime-stats-app-with-firebase/002-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/008-realtime-stats-app-with-firebase/002-final/android/settings.gradle b/008-realtime-stats-app-with-firebase/002-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/AppFrameworkInfo.plist b/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/Debug.xcconfig b/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/Release.xcconfig b/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.pbxproj b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..8f843ba4 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..949b6789 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Original + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/AppDelegate.h b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/AppDelegate.m b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..5bba67f7 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..bcbf413f Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..85071a7f Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..74ca0555 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..c1ab6b62 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..645f3ea4 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..b9e95e26 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..35a779aa Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..8561e1d0 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a645edf5 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..04a5aeae Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..3010c219 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..e6be06ed Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..0e78dc08 Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/Contents.json b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json new file mode 100644 index 00000000..4605c085 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png differ diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..5888d89e --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Base.lproj/Main.storyboard b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Info.plist b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Info.plist new file mode 100644 index 00000000..fa2050a2 --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + skeleton_watcher + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/008-realtime-stats-app-with-firebase/002-final/ios/Runner/main.m b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/008-realtime-stats-app-with-firebase/002-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/enums/view_state.dart b/008-realtime-stats-app-with-firebase/002-final/lib/enums/view_state.dart index 72c2d168..a68c220e 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/enums/view_state.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/enums/view_state.dart @@ -1,13 +1,13 @@ - -/// A value mapping the View UI to the state in the Model. -/// -/// This will contain all the possible states for any view, custom enums can be created for separate views if required -enum ViewState { - Idle, // When nothing is happening or just initialized - Busy, // Typically shows a loading indicator of some sorts - DataFetched, // Indicates that there's data available on the view - NoDataAvailable, // Indicates that data was fetched successfully but nothing is available - Error, // Indicates there's an error on the view - Success, // Successful action occurred - WaitingForInput // The starting state that a form view is in + +/// A value mapping the View UI to the state in the Model. +/// +/// This will contain all the possible states for any view, custom enums can be created for separate views if required +enum ViewState { + Idle, // When nothing is happening or just initialized + Busy, // Typically shows a loading indicator of some sorts + DataFetched, // Indicates that there's data available on the view + NoDataAvailable, // Indicates that data was fetched successfully but nothing is available + Error, // Indicates there's an error on the view + Success, // Successful action occurred + WaitingForInput // The starting state that a form view is in } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/main.dart b/008-realtime-stats-app-with-firebase/002-final/lib/main.dart index 9e431cfb..6e8e5f91 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/main.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/main.dart @@ -1,26 +1,26 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/views/home_view.dart'; -import './service_locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Skeleton Watcher', - theme: ThemeData( - primaryColor: Color.fromARGB(255, 9, 202, 172), - backgroundColor: Color.fromARGB(255, 26, 27, 30), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - bodyColor: Colors.white, - displayColor: Colors.white)), - home: HomeView()); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/views/home_view.dart'; +import './service_locator.dart'; + +void main() { + // Register all the models and services before the app starts + setupLocator(); + + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Skeleton Watcher', + theme: ThemeData( + primaryColor: Color.fromARGB(255, 9, 202, 172), + backgroundColor: Color.fromARGB(255, 26, 27, 30), + textTheme: Theme.of(context).textTheme.apply( + fontFamily: 'Open Sans', + bodyColor: Colors.white, + displayColor: Colors.white)), + home: HomeView()); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/models/list_item.dart b/008-realtime-stats-app-with-firebase/002-final/lib/models/list_item.dart index 726d08b3..f4e10ccd 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/models/list_item.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/models/list_item.dart @@ -1,6 +1,6 @@ -class ListItem { - final String title; - final String description; - - ListItem({this.title, this.description}); +class ListItem { + final String title; + final String description; + + ListItem({this.title, this.description}); } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/models/stats.dart b/008-realtime-stats-app-with-firebase/002-final/lib/models/stats.dart index beb91194..cc070958 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/models/stats.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/models/stats.dart @@ -1,14 +1,14 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -class Stats { - final int userCount; - final int appCount; - final int errorCount; - - Stats({this.userCount, this.appCount, this.errorCount}); - - Stats.fromSnapshot(DocumentSnapshot snapShot) : - appCount = snapShot['appCount'] ?? 0, - userCount = snapShot['userCount'] ?? 0, - errorCount = snapShot['errorCount'] ?? 0; +import 'package:cloud_firestore/cloud_firestore.dart'; + +class Stats { + final int userCount; + final int appCount; + final int errorCount; + + Stats({this.userCount, this.appCount, this.errorCount}); + + Stats.fromSnapshot(DocumentSnapshot snapShot) : + appCount = snapShot['appCount'] ?? 0, + userCount = snapShot['userCount'] ?? 0, + errorCount = snapShot['errorCount'] ?? 0; } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/models/user.dart b/008-realtime-stats-app-with-firebase/002-final/lib/models/user.dart index 7b050e50..6beb5a25 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/models/user.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/models/user.dart @@ -1,14 +1,14 @@ -class User { - final String username; - final String email; - final String userId; - final String accessToken; - - User({this.username, this.email, this.userId, this.accessToken}); - - User.fromJson(Map data) - : username = data['username'], - email = data['email'], - userId = data['userId'], - accessToken = data['accessToken']; -} +class User { + final String username; + final String email; + final String userId; + final String accessToken; + + User({this.username, this.email, this.userId, this.accessToken}); + + User.fromJson(Map data) + : username = data['username'], + email = data['email'], + userId = data['userId'], + accessToken = data['accessToken']; +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/base_model.dart b/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/base_model.dart index c66dd850..edee34fa 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/base_model.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/base_model.dart @@ -1,17 +1,17 @@ -import 'package:scoped_model/scoped_model.dart'; - -import 'package:skeleton_watcher/enums/view_state.dart'; -// Make sure state enum is accessible in all inherting models -export 'package:skeleton_watcher/enums/view_state.dart'; - -class BaseModel extends Model { - ViewState _state = ViewState.Idle; - ViewState get state => _state; - - void setState(ViewState newState) { - _state = newState; - - // Notify listeners will only update listeners of state. - notifyListeners(); - } -} +import 'package:scoped_model/scoped_model.dart'; + +import 'package:skeleton_watcher/enums/view_state.dart'; +// Make sure state enum is accessible in all inherting models +export 'package:skeleton_watcher/enums/view_state.dart'; + +class BaseModel extends Model { + ViewState _state = ViewState.Idle; + ViewState get state => _state; + + void setState(ViewState newState) { + _state = newState; + + // Notify listeners will only update listeners of state. + notifyListeners(); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/feedback_view_model.dart b/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/feedback_view_model.dart index 3a9c6ff8..e1a79020 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/feedback_view_model.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/feedback_view_model.dart @@ -1,28 +1,27 @@ -import 'package:skeleton_watcher/models/list_item.dart'; -import 'base_model.dart'; - -export 'package:skeleton_watcher/enums/view_state.dart'; - -/// Contains logic for a list view with the general expected functionality. -class FeedbackViewModel extends BaseModel { - List listData; - - Future fetchListData() async { - setState(ViewState.Busy); - - await Future.delayed(Duration(seconds: 1)); - listData = List.generate( - 10, - (index) => ListItem( - title: 'title $index', - description: 'Description of this list Item. $index')); - - if (listData == null) { - setState(ViewState.Error); - } else { - setState(listData.length == 0 - ? ViewState.NoDataAvailable - : ViewState.DataFetched); - } - } -} +import 'package:scoped_model/scoped_model.dart'; +import 'package:skeleton_watcher/models/list_item.dart'; +import 'base_model.dart'; + +export 'package:skeleton_watcher/enums/view_state.dart'; + + +/// Contains logic for a list view with the general expected functionality. +class FeedbackViewModel extends BaseModel { + List listData; + + Future fetchListData() async { + setState(ViewState.Busy); + + await Future.delayed(Duration(seconds: 1)); + listData = List.generate(10, (index) => + ListItem(title: 'title $index', description: 'Description of this list Item. $index')); + + if (listData == null) { + setState(ViewState.Error); + } else { + setState(listData.length == 0 + ? ViewState.NoDataAvailable + : ViewState.DataFetched); + } + } +} \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/home_view_model.dart b/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/home_view_model.dart index 43e38db2..fcd7c199 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/home_view_model.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/scoped_models/home_view_model.dart @@ -1,25 +1,25 @@ -import 'package:skeleton_watcher/models/stats.dart'; -import 'package:skeleton_watcher/service_locator.dart'; -import 'package:skeleton_watcher/services/firebase_service.dart'; - -import 'base_model.dart'; - -class HomeViewModel extends BaseModel { - FirebaseService _firebaseService = locator(); - Stats appStats; - - HomeViewModel() { - _firebaseService.appStats.listen(_onStatsUpdated); - } - - void _onStatsUpdated(Stats stats) { - appStats = stats; // Set the stats for the UI - - if (stats == null) { - setState(ViewState.Busy); // If null indicate we're still fetching - } else { - setState(ViewState - .DataFetched); // When not null indicate that the data is fetched - } - } -} +import 'package:skeleton_watcher/models/stats.dart'; +import 'package:skeleton_watcher/service_locator.dart'; +import 'package:skeleton_watcher/services/firebase_service.dart'; + +import 'base_model.dart'; + +class HomeViewModel extends BaseModel { + FirebaseService _firebaseService = locator(); + Stats appStats; + + HomeViewModel() { + _firebaseService.appStats.listen(_onStatsUpdated); + } + + void _onStatsUpdated(Stats stats) { + appStats = stats; // Set the stats for the UI + + if (stats == null) { + setState(ViewState.Busy); // If null indicate we're still fetching + } else { + setState(ViewState + .DataFetched); // When not null indicate that the data is fetched + } + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/service_locator.dart b/008-realtime-stats-app-with-firebase/002-final/lib/service_locator.dart index 46cf324e..aec830bc 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/service_locator.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/service_locator.dart @@ -1,15 +1,16 @@ -import 'package:get_it/get_it.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; -import 'package:skeleton_watcher/services/firebase_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - // Register services - locator.registerLazySingleton(() => FirebaseService()); - - // Register ScopedModels - locator.registerFactory(() => HomeViewModel()); - locator.registerFactory(() => FeedbackViewModel()); -} +import 'package:get_it/get_it.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; +import 'package:skeleton_watcher/services/firebase_service.dart'; + +GetIt locator = new GetIt(); + +void setupLocator() { + // Register services + locator.registerLazySingleton(() => FirebaseService()); + + // Register ScopedModels + locator.registerFactory(() => HomeViewModel()); + locator.registerFactory(() => FeedbackViewModel()); +} + diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/services/firebase_service.dart b/008-realtime-stats-app-with-firebase/002-final/lib/services/firebase_service.dart index fa40732c..d8340374 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/services/firebase_service.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/services/firebase_service.dart @@ -1,22 +1,22 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:skeleton_watcher/models/stats.dart'; - -class FirebaseService { - final StreamController _statsController = StreamController(); - - FirebaseService() { - Firestore.instance - .collection('informations') - .document('project_stats') - .snapshots() - .listen(_statsUpdated); - } - - Stream get appStats => _statsController.stream; - - void _statsUpdated(DocumentSnapshot snapshot) { - _statsController.add(Stats.fromSnapshot(snapshot)); - } -} +import 'dart:async'; + +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:skeleton_watcher/models/stats.dart'; + +class FirebaseService { + final StreamController _statsController = StreamController(); + + FirebaseService() { + Firestore.instance + .collection('informations') + .document('project_stats') + .snapshots() + .listen(_statsUpdated); + } + + Stream get appStats => _statsController.stream; + + void _statsUpdated(DocumentSnapshot snapshot) { + _statsController.add(Stats.fromSnapshot(snapshot)); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/app_colors.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/app_colors.dart index e5ca3a2c..d976c11e 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/app_colors.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/app_colors.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); +import 'package:flutter/material.dart'; + +const Color lightGrey = Color.fromARGB(255,61,63,69); +const Color darkGrey = Color.fromARGB(255,18,18,19); +const Color primaryColor = Color.fromARGB(255, 9, 202, 172); +const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/font_styles.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/font_styles.dart index d224f955..bed44618 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/font_styles.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/font_styles.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); const TextStyle viewErrorTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800, color: lightGrey); \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_helpers.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_helpers.dart index 8665bf7c..390780a6 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_helpers.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_helpers.dart @@ -1,114 +1,114 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 20.0; - static const double _VerticalSpaceMedium = 40.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 20.0; - static const double _HorizontalSpaceMedium = 40.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } - - /// Provides an input field with a title that stretches the full width of the screen - static Widget inputField({ - String title, - String placeholder, - @required TextEditingController controller, - String validationMessage, - bool isPassword = false, - double spaceBetweenTitle = 15.0, - double padding = 10.0}) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), - validationMessage != null ? Text( - validationMessage, - style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), - Container( - alignment: Alignment(0.0, 0.0), - padding: EdgeInsets.only(left: padding), - margin: EdgeInsets.only(top: spaceBetweenTitle), - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: lightGrey - ), - child: TextField( - controller: controller, - obscureText: isPassword, - style: TextStyle(fontSize: 12.0), - decoration: InputDecoration.collapsed( - hintText: placeholder, - hintStyle: - TextStyle(color: Colors.grey[600], fontSize: 12.0)), - ), - ) - ]); - } - - static Widget fullScreenButton({ - String title, - Function onTap - }) { - return GestureDetector( - onTap: onTap , - child: Container( - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Color.fromARGB(255, 9, 202, 172)), - child: Center( - child: - Text(title, style: TextStyle(fontWeight: FontWeight.w800))), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +/// Contains useful functions to reduce boilerplate code +class UIHelper { + // Vertical spacing constants. Adjust to your liking. + static const double _VerticalSpaceSmall = 20.0; + static const double _VerticalSpaceMedium = 40.0; + static const double _VerticalSpaceLarge = 60.0; + + // Vertical spacing constants. Adjust to your liking. + static const double _HorizontalSpaceSmall = 20.0; + static const double _HorizontalSpaceMedium = 40.0; + static const double HorizontalSpaceLarge = 60.0; + + /// Returns a vertical space with height set to [_VerticalSpaceSmall] + static Widget verticalSpaceSmall() { + return verticalSpace(_VerticalSpaceSmall); + } + + /// Returns a vertical space with height set to [_VerticalSpaceMedium] + static Widget verticalSpaceMedium() { + return verticalSpace(_VerticalSpaceMedium); + } + + /// Returns a vertical space with height set to [_VerticalSpaceLarge] + static Widget verticalSpaceLarge() { + return verticalSpace(_VerticalSpaceLarge); + } + + /// Returns a vertical space equal to the [height] supplied + static Widget verticalSpace(double height) { + return Container(height: height); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceSmall] + static Widget horizontalSpaceSmall() { + return horizontalSpace(_HorizontalSpaceSmall); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceMedium] + static Widget horizontalSpaceMedium() { + return horizontalSpace(_HorizontalSpaceMedium); + } + + /// Returns a vertical space with height set to [HorizontalSpaceLarge] + static Widget horizontalSpaceLarge() { + return horizontalSpace(HorizontalSpaceLarge); + } + + /// Returns a vertical space equal to the [width] supplied + static Widget horizontalSpace(double width) { + return Container(width: width); + } + + /// Provides an input field with a title that stretches the full width of the screen + static Widget inputField({ + String title, + String placeholder, + @required TextEditingController controller, + String validationMessage, + bool isPassword = false, + double spaceBetweenTitle = 15.0, + double padding = 10.0}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, + style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), + validationMessage != null ? Text( + validationMessage, + style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), + Container( + alignment: Alignment(0.0, 0.0), + padding: EdgeInsets.only(left: padding), + margin: EdgeInsets.only(top: spaceBetweenTitle), + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: lightGrey + ), + child: TextField( + controller: controller, + obscureText: isPassword, + style: TextStyle(fontSize: 12.0), + decoration: InputDecoration.collapsed( + hintText: placeholder, + hintStyle: + TextStyle(color: Colors.grey[600], fontSize: 12.0)), + ), + ) + ]); + } + + static Widget fullScreenButton({ + String title, + Function onTap + }) { + return GestureDetector( + onTap: onTap , + child: Container( + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: Color.fromARGB(255, 9, 202, 172)), + child: Center( + child: + Text(title, style: TextStyle(fontWeight: FontWeight.w800))), + ), + ); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_reducers.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_reducers.dart index 54c9c712..0e8b0fb4 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_reducers.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/shared/ui_reducers.dart @@ -1,7 +1,7 @@ -import 'package:flutter/widgets.dart'; - -double screenHeight(BuildContext context, - {int dividedBy = 1, double decreasedBy = 0.0}) { - assert(dividedBy != 0, "Don't divide by 0"); - return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; -} +import 'package:flutter/widgets.dart'; + +double screenHeight(BuildContext context, + {int dividedBy = 1, double decreasedBy = 0.0}) { + assert(dividedBy != 0, "Don't divide by 0"); + return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/base_view.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/base_view.dart index 042f5f47..dcda33b3 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/base_view.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/base_view.dart @@ -1,40 +1,40 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_model/scoped_model.dart'; -import 'package:skeleton_watcher/service_locator.dart'; - -class BaseView extends StatefulWidget { - - final ScopedModelDescendantBuilder _builder; - - /// Function will be called as soon as the widget is initialised. - /// - /// Callback will reive the model that was created and supplied to the ScopedModel - final Function(T) onModelReady; - - BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) - : _builder = builder; - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T _model = locator(); - - @override - void initState() { - if(widget.onModelReady != null) { - widget.onModelReady(_model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ScopedModel( - model: _model, - child: ScopedModelDescendant( - child: Container(color: Colors.red), - builder: widget._builder)); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:skeleton_watcher/service_locator.dart'; + +class BaseView extends StatefulWidget { + + final ScopedModelDescendantBuilder _builder; + + /// Function will be called as soon as the widget is initialised. + /// + /// Callback will reive the model that was created and supplied to the ScopedModel + final Function(T) onModelReady; + + BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) + : _builder = builder; + + @override + _BaseViewState createState() => _BaseViewState(); +} + +class _BaseViewState extends State> { + T _model = locator(); + + @override + void initState() { + if(widget.onModelReady != null) { + widget.onModelReady(_model); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ScopedModel( + model: _model, + child: ScopedModelDescendant( + child: Container(color: Colors.red), + builder: widget._builder)); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/feedback_view.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/feedback_view.dart index 8abadc60..d0660247 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/feedback_view.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/feedback_view.dart @@ -1,109 +1,109 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/models/list_item.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; -import 'package:skeleton_watcher/ui/shared/font_styles.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; - -class FeedbackView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.fetchListData(), - builder: (context, childe, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: Container(child: _getBodyUi(context, model)))); - } - - Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { - switch (model.state) { - case ViewState.Busy: - return _getLoadingUi(context); - case ViewState.NoDataAvailable: - return _noDataUi(context, model); - case ViewState.Error: - return _errorUi(context, model); - case ViewState.DataFetched: - default: - return _getListUi(model); - } - } - - Widget _getListUi(FeedbackViewModel model) { - return ListView.builder( - itemCount: model.listData.length, - itemBuilder: (context, itemIndex) { - var item = model.listData[itemIndex]; - return _getListItemUi(item); - }); - } - - Container _getListItemUi(ListItem result) { - return Container( - height: 100.0, - margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: lightGrey), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(result.title, style: viewTitle), - Text(result.description) - ], - ), - ); - } - - Widget _getLoadingUi(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator( - valueColor: - AlwaysStoppedAnimation(Theme.of(context).primaryColor)), - Text('Fetching data ...') - ], - )); - } - - Widget _noDataUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage( - context, - "No data available yet", - model); - } - - Widget _errorUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage( - context, - "Error retrieving your data. Tap to try again", - model, - error: true); - } - - Widget _getCenteredViewMessage( - BuildContext context, String message, FeedbackViewModel model, - {bool error = false}) { - return Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - message, - style: viewErrorTitle, - textAlign: TextAlign.center, - ), - error - ? Icon( // WWrap in gesture detector and call you refresh future here - Icons.refresh, - color: Colors.white, - size: 45.0, - ) - : Container() - ], - ))); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/models/list_item.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; +import 'package:skeleton_watcher/ui/shared/font_styles.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; + +class FeedbackView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.fetchListData(), + builder: (context, childe, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: Container(child: _getBodyUi(context, model)))); + } + + Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { + switch (model.state) { + case ViewState.Busy: + return _getLoadingUi(context); + case ViewState.NoDataAvailable: + return _noDataUi(context, model); + case ViewState.Error: + return _errorUi(context, model); + case ViewState.DataFetched: + default: + return _getListUi(model); + } + } + + Widget _getListUi(FeedbackViewModel model) { + return ListView.builder( + itemCount: model.listData.length, + itemBuilder: (context, itemIndex) { + var item = model.listData[itemIndex]; + return _getListItemUi(item); + }); + } + + Container _getListItemUi(ListItem result) { + return Container( + height: 100.0, + margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: lightGrey), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(result.title, style: viewTitle), + Text(result.description) + ], + ), + ); + } + + Widget _getLoadingUi(BuildContext context) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation(Theme.of(context).primaryColor)), + Text('Fetching data ...') + ], + )); + } + + Widget _noDataUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage( + context, + "No data available yet", + model); + } + + Widget _errorUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage( + context, + "Error retrieving your data. Tap to try again", + model, + error: true); + } + + Widget _getCenteredViewMessage( + BuildContext context, String message, FeedbackViewModel model, + {bool error = false}) { + return Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + message, + style: viewErrorTitle, + textAlign: TextAlign.center, + ), + error + ? Icon( // WWrap in gesture detector and call you refresh future here + Icons.refresh, + color: Colors.white, + size: 45.0, + ) + : Container() + ], + ))); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/home_view.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/home_view.dart index 709898a0..b1f89416 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/home_view.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/views/home_view.dart @@ -1,92 +1,92 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/enums/view_state.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; -import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; -import 'package:skeleton_watcher/ui/views/feedback_view.dart'; -import 'package:skeleton_watcher/ui/widgets/indicator_button.dart'; -import 'package:skeleton_watcher/ui/widgets/stats_counter.dart'; -import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; - -class HomeView extends StatelessWidget { - static const BoxDecoration topLineBorderDecoration = BoxDecoration( - border: Border( - top: BorderSide( - color: lightGrey, style: BorderStyle.solid, width: 5.0))); - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, child, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: _getBody(model, context))); - } - - Widget _getBody(HomeViewModel model, BuildContext context) { - switch (model.state) { - case ViewState.Busy: - case ViewState.Idle: - return Center(child: CircularProgressIndicator()); - default: - return _getStatsUi(model, context); - } - } - - Widget _getStatsUi(HomeViewModel model, BuildContext context) { - return Column(children: [ - WatcherToolbar(title: 'SKELETON-WATCHER'), - _getHeightContainer( - context: context, - height: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), - child: StatsCounter( - size: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight) - 60, // 60 margins - count: model.appStats.errorCount, - title: 'Errors', - titleColor: Colors.red, - ), - ), - _getHeightContainer( - context: context, - height:screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - StatsCounter( - size: screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight) - 60, - count: model.appStats.userCount, - title: 'Users', - ), - StatsCounter( - size: screenHeight(context,dividedBy: 3, decreasedBy: toolbarHeight) - 60, - count: model.appStats.appCount, - title: 'Apps Created', - ) - ]) - ), - _getHeightContainer( - height:screenHeight(context, dividedBy: 6, decreasedBy: toolbarHeight), - child: IndicatorButton( - title: 'FEEDBACK', - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => FeedbackView())); - } - )) - ]); - } - - Widget _getHeightContainer( - {double height, - BuildContext context, - Widget child, - bool hasTopStroke = false}) { - return Container( - height: height, - alignment: Alignment.center, - margin: EdgeInsets.symmetric(horizontal: 20.0), - decoration: hasTopStroke? topLineBorderDecoration : null, - child: child); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/enums/view_state.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; +import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; +import 'package:skeleton_watcher/ui/views/feedback_view.dart'; +import 'package:skeleton_watcher/ui/widgets/indicator_button.dart'; +import 'package:skeleton_watcher/ui/widgets/stats_counter.dart'; +import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; + +class HomeView extends StatelessWidget { + static const BoxDecoration topLineBorderDecoration = BoxDecoration( + border: Border( + top: BorderSide( + color: lightGrey, style: BorderStyle.solid, width: 5.0))); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, child, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: _getBody(model, context))); + } + + Widget _getBody(HomeViewModel model, BuildContext context) { + switch (model.state) { + case ViewState.Busy: + case ViewState.Idle: + return Center(child: CircularProgressIndicator()); + default: + return _getStatsUi(model, context); + } + } + + Widget _getStatsUi(HomeViewModel model, BuildContext context) { + return Column(children: [ + WatcherToolbar(title: 'SKELETON-WATCHER'), + _getHeightContainer( + context: context, + height: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), + child: StatsCounter( + size: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight) - 60, // 60 margins + count: model.appStats.errorCount, + title: 'Errors', + titleColor: Colors.red, + ), + ), + _getHeightContainer( + context: context, + height:screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + StatsCounter( + size: screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight) - 60, + count: model.appStats.userCount, + title: 'Users', + ), + StatsCounter( + size: screenHeight(context,dividedBy: 3, decreasedBy: toolbarHeight) - 60, + count: model.appStats.appCount, + title: 'Apps Created', + ) + ]) + ), + _getHeightContainer( + height:screenHeight(context, dividedBy: 6, decreasedBy: toolbarHeight), + child: IndicatorButton( + title: 'FEEDBACK', + onTap: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => FeedbackView())); + } + )) + ]); + } + + Widget _getHeightContainer( + {double height, + BuildContext context, + Widget child, + bool hasTopStroke = false}) { + return Container( + height: height, + alignment: Alignment.center, + margin: EdgeInsets.symmetric(horizontal: 20.0), + decoration: hasTopStroke? topLineBorderDecoration : null, + child: child); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/busy_overlay.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/busy_overlay.dart index 24f0f4b6..f2617207 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/busy_overlay.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/busy_overlay.dart @@ -1,45 +1,45 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} +import 'package:flutter/material.dart'; + +/// A modal overlay that will show over your child widget (fullscreen) when the show value is true +/// +/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when +/// your model state is Busy +class BusyOverlay extends StatelessWidget { + final Widget child; + final String title; + final bool show; + + const BusyOverlay({this.child, + this.title = 'Please wait...', + this.show = false}); + + @override + Widget build(BuildContext context) { + var screenSize = MediaQuery.of(context).size; + return Material( + child: Stack(children: [ + child, + IgnorePointer( + child: Opacity( + opacity: show ? 1.0 : 0.0, + child: Container( + width: screenSize.width, + height: screenSize.height, + alignment: Alignment.center, + color: Color.fromARGB(100, 0, 0, 0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(), + Text(title, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + )), + ), + ])); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/indicator_button.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/indicator_button.dart index 6cb88f6b..d617fe2a 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/indicator_button.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/indicator_button.dart @@ -1,47 +1,47 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -class IndicatorButton extends StatelessWidget { - final double height; - final String title; - final Function onTap; - final int indicationCount; - - const IndicatorButton({this.height = 50.0, this.title, this.onTap, this.indicationCount}); - - bool get hasIndication => indicationCount != null && indicationCount > 0; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - height: height, - child: Stack(children: [ - Container( - height: height, - width: double.infinity, - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: primaryColor), - child: Text( - title, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), - )), - hasIndication ? Positioned( - top: 10, - right: 20.0, - child: Container( - width: 30, - height: 30, - alignment: Alignment.center, - decoration: - ShapeDecoration(shape: CircleBorder(), color: darkGrey), - child: Text(indicationCount.toString(), - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400)), - ), - ) : Container() - ]), - )); - } +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +class IndicatorButton extends StatelessWidget { + final double height; + final String title; + final Function onTap; + final int indicationCount; + + const IndicatorButton({this.height = 50.0, this.title, this.onTap, this.indicationCount}); + + bool get hasIndication => indicationCount != null && indicationCount > 0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + height: height, + child: Stack(children: [ + Container( + height: height, + width: double.infinity, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: primaryColor), + child: Text( + title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), + )), + hasIndication ? Positioned( + top: 10, + right: 20.0, + child: Container( + width: 30, + height: 30, + alignment: Alignment.center, + decoration: + ShapeDecoration(shape: CircleBorder(), color: darkGrey), + child: Text(indicationCount.toString(), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400)), + ), + ) : Container() + ]), + )); + } } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/stats_counter.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/stats_counter.dart index 5d4c38e3..33532d5b 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/stats_counter.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/stats_counter.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -class StatsCounter extends StatelessWidget { - final double size; - final int count; - final String title; - final Color titleColor; - - StatsCounter( - {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); - - @override - Widget build(BuildContext context) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: darkGrey), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text(count.toString(), - textAlign: TextAlign.center, - style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), - Text(title, - textAlign: TextAlign.center, - style: TextStyle( - color: titleColor, - fontSize: size * 0.1, fontWeight: FontWeight.w400)) - ]), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +class StatsCounter extends StatelessWidget { + final double size; + final int count; + final String title; + final Color titleColor; + + StatsCounter( + {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); + + @override + Widget build(BuildContext context) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: darkGrey), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(count.toString(), + textAlign: TextAlign.center, + style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), + Text(title, + textAlign: TextAlign.center, + style: TextStyle( + color: titleColor, + fontSize: size * 0.1, fontWeight: FontWeight.w400)) + ]), + ); + } +} diff --git a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/watcher_toolbar.dart b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/watcher_toolbar.dart index afaf138d..8161765e 100644 --- a/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/watcher_toolbar.dart +++ b/008-realtime-stats-app-with-firebase/002-final/lib/ui/widgets/watcher_toolbar.dart @@ -1,38 +1,38 @@ -import 'package:flutter/material.dart'; - -const double toolbarHeight = 80.0; - -class WatcherToolbar extends StatelessWidget { - final String title; - final bool showBackButton; - const WatcherToolbar({@required this.title, this.showBackButton = false}); - - @override - Widget build(BuildContext context) { - return Container( - height: toolbarHeight, - margin: EdgeInsets.symmetric(horizontal: 20.0), - child: Row( - children: [ - showBackButton - ? GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.centerLeft, - width: 50, - child: Icon(Icons.chevron_left, - size: 30, color: Colors.white)), - ) - : Container(), - Expanded( - child: Text(title, - textAlign: TextAlign.right, - style: TextStyle(fontWeight: FontWeight.w800)), - ), - ], - ), - ); - } +import 'package:flutter/material.dart'; + +const double toolbarHeight = 80.0; + +class WatcherToolbar extends StatelessWidget { + final String title; + final bool showBackButton; + const WatcherToolbar({@required this.title, this.showBackButton = false}); + + @override + Widget build(BuildContext context) { + return Container( + height: toolbarHeight, + margin: EdgeInsets.symmetric(horizontal: 20.0), + child: Row( + children: [ + showBackButton + ? GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Container( + alignment: Alignment.centerLeft, + width: 50, + child: Icon(Icons.chevron_left, + size: 30, color: Colors.white)), + ) + : Container(), + Expanded( + child: Text(title, + textAlign: TextAlign.right, + style: TextStyle(fontWeight: FontWeight.w800)), + ), + ], + ), + ); + } } \ No newline at end of file diff --git a/008-realtime-stats-app-with-firebase/002-final/pubspec.lock b/008-realtime-stats-app-with-firebase/002-final/pubspec.lock index 6afbe482..10d0e190 100644 --- a/008-realtime-stats-app-with-firebase/002-final/pubspec.lock +++ b/008-realtime-stats-app-with-firebase/002-final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,28 +7,21 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.2.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" cloud_firestore: dependency: "direct main" description: @@ -42,21 +35,14 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" firebase_core: dependency: transitive description: @@ -80,28 +66,42 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "1.0.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" scoped_model: dependency: "direct main" description: @@ -120,7 +120,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -155,7 +155,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.5" typed_data: dependency: transitive description: @@ -171,5 +171,5 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" flutter: ">=1.2.0 <2.0.0" diff --git a/008-realtime-stats-app-with-firebase/002-final/pubspec.yaml b/008-realtime-stats-app-with-firebase/002-final/pubspec.yaml index 4ab6d96d..b9aafeca 100644 --- a/008-realtime-stats-app-with-firebase/002-final/pubspec.yaml +++ b/008-realtime-stats-app-with-firebase/002-final/pubspec.yaml @@ -1,76 +1,78 @@ -name: skeleton_watcher -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # scoped model packages - scoped_model: ^1.0.1 - # get it - get_it: ^4.0.2 - # firebase firestore - cloud_firestore: - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: skeleton_watcher +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + # scoped model packages + scoped_model: ^1.0.1 + # get it + get_it: ^1.0.3 + # firebase firestore + cloud_firestore: + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: Open Sans + fonts: + - asset: assets/fonts/OpenSans-Bold.ttf + weight: 700 + - asset: assets/fonts/OpenSans-ExtraBold.ttf + weight: 800 + - asset: assets/fonts/OpenSans-Light.ttf + weight: 300 + - asset: assets/fonts/OpenSans-Regular.ttf + weight: 400 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/008-realtime-stats-app-with-firebase/002-final/test/widget_test.dart b/008-realtime-stats-app-with-firebase/002-final/test/widget_test.dart index ee9c85de..688c5230 100644 --- a/008-realtime-stats-app-with-firebase/002-final/test/widget_test.dart +++ b/008-realtime-stats-app-with-firebase/002-final/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:skeleton_watcher/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:skeleton_watcher/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/008-realtime-stats-app-with-firebase/README.md b/008-realtime-stats-app-with-firebase/README.md index 0a2de2ff..7b9e77ff 100644 --- a/008-realtime-stats-app-with-firebase/README.md +++ b/008-realtime-stats-app-with-firebase/README.md @@ -1,3 +1,3 @@ -# Skeleton Watcher Code - +# Skeleton Watcher Code + This is the code (without my googleplay-service.json) file that I use to monitor my app stats. \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/.flutter-plugins-dependencies b/009-realtime-feedback-app/001-start/.flutter-plugins-dependencies deleted file mode 100644 index 9779eb92..00000000 --- a/009-realtime-feedback-app/001-start/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.10.0/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.3.4/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.10.0/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.3.4/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core"]},{"name":"firebase_core","dependencies":[]}],"date_created":"2020-06-18 21:49:01.631889","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/.gitignore b/009-realtime-feedback-app/001-start/.gitignore index 5be59a14..07488ba6 100644 --- a/009-realtime-feedback-app/001-start/.gitignore +++ b/009-realtime-feedback-app/001-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/009-realtime-feedback-app/001-start/.metadata b/009-realtime-feedback-app/001-start/.metadata index 0012359c..32e51230 100644 --- a/009-realtime-feedback-app/001-start/.metadata +++ b/009-realtime-feedback-app/001-start/.metadata @@ -1,10 +1,10 @@ -# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app +# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff + channel: master + +project_type: app diff --git a/009-realtime-feedback-app/001-start/README.md b/009-realtime-feedback-app/001-start/README.md index 9b0e6f2b..e2a9cf07 100644 --- a/009-realtime-feedback-app/001-start/README.md +++ b/009-realtime-feedback-app/001-start/README.md @@ -1,82 +1,82 @@ -# Flutter using AppSkeletons - ScopedModel architecture - -This project has been generated with [AppSkeletons](https://www.appskeletons.com). - -This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. - -ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. - -### About this template - -There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. - -#### One AppModel with FeatureModel mixins -In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. - -**Pros:** - - State is managed in one place (and all the benefits of that). - - All functionality is Easily accessible from one model using inherited widget functionality. - - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. - -**Cons:** - - notifyListeners can have multiple bindings alive at any point. - - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. - - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. - -#### One Model per view - -**Pros:** - - View has it's own dedicated Model - - All state functionality and reduction for a view is contained in it's own Model - - Better logical and mental grouping (View + View's Model) - -**Cons:** - - More Models to be aware of and manage - - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) - - Harder to make use of Logic from other models (which should never happen anyway) - -I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. - -### The implementation - -This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. - -Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. - -## Getting Started - -1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. -2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio -3. Run application - -## Structure and placement - -The root folder is split into 4 sections, models, scoped_models, services and ui. - -### Models - -Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. - -### Scoped Models - -In this scoped_models folder you'll place all the models associated with your views. One per view. - -**Naming convention:** [viewname]_model.dart i.e. home_model.dart - -### Services - -This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. - -**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart - -### UI - -Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. - -**views/**: Contains the files for each of the views in your applications. - -Naming convention: [viewname]_view.dart - -## Conclusion - +# Flutter using AppSkeletons - ScopedModel architecture + +This project has been generated with [AppSkeletons](https://www.appskeletons.com). + +This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. + +ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. + +### About this template + +There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. + +#### One AppModel with FeatureModel mixins +In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. + +**Pros:** + - State is managed in one place (and all the benefits of that). + - All functionality is Easily accessible from one model using inherited widget functionality. + - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. + +**Cons:** + - notifyListeners can have multiple bindings alive at any point. + - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. + - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. + +#### One Model per view + +**Pros:** + - View has it's own dedicated Model + - All state functionality and reduction for a view is contained in it's own Model + - Better logical and mental grouping (View + View's Model) + +**Cons:** + - More Models to be aware of and manage + - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) + - Harder to make use of Logic from other models (which should never happen anyway) + +I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. + +### The implementation + +This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. + +Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. + +## Getting Started + +1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. +2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio +3. Run application + +## Structure and placement + +The root folder is split into 4 sections, models, scoped_models, services and ui. + +### Models + +Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. + +### Scoped Models + +In this scoped_models folder you'll place all the models associated with your views. One per view. + +**Naming convention:** [viewname]_model.dart i.e. home_model.dart + +### Services + +This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. + +**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart + +### UI + +Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. + +**views/**: Contains the files for each of the views in your applications. + +Naming convention: [viewname]_view.dart + +## Conclusion + There are many other things you can setup in your app all depending on your code style. I have a full video on my [Youtube channel](https://www.youtube.com/channel/UC2d0BYlqQCdF9lJfydl_02Q) describing how to setup this template from scratch. \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/android/app/build.gradle b/009-realtime-feedback-app/001-start/android/app/build.gradle new file mode 100644 index 00000000..0e1f6e02 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/build.gradle @@ -0,0 +1,66 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.appskeletons.skeleton_watcher" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + multiDexEnabled true + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'com.google.firebase:firebase-core:16.0.1' + implementation 'com.android.support:multidex:1.0.3' +} + +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/android/app/src/debug/AndroidManifest.xml b/009-realtime-feedback-app/001-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/AndroidManifest.xml b/009-realtime-feedback-app/001-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..92f71cc8 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java b/009-realtime-feedback-app/001-start/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java new file mode 100644 index 00000000..6e695021 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java @@ -0,0 +1,13 @@ +package com.appskeletons.skeleton_watcher; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/drawable/launch_background.xml b/009-realtime-feedback-app/001-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..219bdbfa --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..70cde7e6 Binary files /dev/null and b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..34d76500 Binary files /dev/null and b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..03ca164d Binary files /dev/null and b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..5cbbce61 Binary files /dev/null and b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..3ce53d50 Binary files /dev/null and b/009-realtime-feedback-app/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/values/colors.xml b/009-realtime-feedback-app/001-start/android/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..d88c48a0 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #1A1B1E + \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/android/app/src/main/res/values/styles.xml b/009-realtime-feedback-app/001-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/009-realtime-feedback-app/001-start/android/app/src/profile/AndroidManifest.xml b/009-realtime-feedback-app/001-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/009-realtime-feedback-app/001-start/android/build.gradle b/009-realtime-feedback-app/001-start/android/build.gradle new file mode 100644 index 00000000..3e107571 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/build.gradle @@ -0,0 +1,30 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.google.gms:google-services:4.0.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/009-realtime-feedback-app/001-start/android/gradle.properties b/009-realtime-feedback-app/001-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/009-realtime-feedback-app/001-start/android/gradle/wrapper/gradle-wrapper.properties b/009-realtime-feedback-app/001-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/009-realtime-feedback-app/001-start/android/settings.gradle b/009-realtime-feedback-app/001-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/009-realtime-feedback-app/001-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/009-realtime-feedback-app/001-start/ios/Flutter/AppFrameworkInfo.plist b/009-realtime-feedback-app/001-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/009-realtime-feedback-app/001-start/ios/Flutter/Debug.xcconfig b/009-realtime-feedback-app/001-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/009-realtime-feedback-app/001-start/ios/Flutter/Release.xcconfig b/009-realtime-feedback-app/001-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.pbxproj b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..8f843ba4 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/009-realtime-feedback-app/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/009-realtime-feedback-app/001-start/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..949b6789 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Original + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner/AppDelegate.h b/009-realtime-feedback-app/001-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/009-realtime-feedback-app/001-start/ios/Runner/AppDelegate.m b/009-realtime-feedback-app/001-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..5bba67f7 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..bcbf413f Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..85071a7f Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..74ca0555 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..c1ab6b62 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..645f3ea4 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..b9e95e26 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..35a779aa Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..8561e1d0 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a645edf5 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..04a5aeae Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..3010c219 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..e6be06ed Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..0e78dc08 Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/Contents.json b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json new file mode 100644 index 00000000..4605c085 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/009-realtime-feedback-app/001-start/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png differ diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/009-realtime-feedback-app/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..5888d89e --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Base.lproj/Main.storyboard b/009-realtime-feedback-app/001-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner/Info.plist b/009-realtime-feedback-app/001-start/ios/Runner/Info.plist new file mode 100644 index 00000000..fa2050a2 --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + skeleton_watcher + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/009-realtime-feedback-app/001-start/ios/Runner/main.m b/009-realtime-feedback-app/001-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/009-realtime-feedback-app/001-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/enums/view_state.dart b/009-realtime-feedback-app/001-start/lib/enums/view_state.dart index 72c2d168..a68c220e 100644 --- a/009-realtime-feedback-app/001-start/lib/enums/view_state.dart +++ b/009-realtime-feedback-app/001-start/lib/enums/view_state.dart @@ -1,13 +1,13 @@ - -/// A value mapping the View UI to the state in the Model. -/// -/// This will contain all the possible states for any view, custom enums can be created for separate views if required -enum ViewState { - Idle, // When nothing is happening or just initialized - Busy, // Typically shows a loading indicator of some sorts - DataFetched, // Indicates that there's data available on the view - NoDataAvailable, // Indicates that data was fetched successfully but nothing is available - Error, // Indicates there's an error on the view - Success, // Successful action occurred - WaitingForInput // The starting state that a form view is in + +/// A value mapping the View UI to the state in the Model. +/// +/// This will contain all the possible states for any view, custom enums can be created for separate views if required +enum ViewState { + Idle, // When nothing is happening or just initialized + Busy, // Typically shows a loading indicator of some sorts + DataFetched, // Indicates that there's data available on the view + NoDataAvailable, // Indicates that data was fetched successfully but nothing is available + Error, // Indicates there's an error on the view + Success, // Successful action occurred + WaitingForInput // The starting state that a form view is in } \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/lib/main.dart b/009-realtime-feedback-app/001-start/lib/main.dart index 9e431cfb..6e8e5f91 100644 --- a/009-realtime-feedback-app/001-start/lib/main.dart +++ b/009-realtime-feedback-app/001-start/lib/main.dart @@ -1,26 +1,26 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/views/home_view.dart'; -import './service_locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Skeleton Watcher', - theme: ThemeData( - primaryColor: Color.fromARGB(255, 9, 202, 172), - backgroundColor: Color.fromARGB(255, 26, 27, 30), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - bodyColor: Colors.white, - displayColor: Colors.white)), - home: HomeView()); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/views/home_view.dart'; +import './service_locator.dart'; + +void main() { + // Register all the models and services before the app starts + setupLocator(); + + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Skeleton Watcher', + theme: ThemeData( + primaryColor: Color.fromARGB(255, 9, 202, 172), + backgroundColor: Color.fromARGB(255, 26, 27, 30), + textTheme: Theme.of(context).textTheme.apply( + fontFamily: 'Open Sans', + bodyColor: Colors.white, + displayColor: Colors.white)), + home: HomeView()); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/models/list_item.dart b/009-realtime-feedback-app/001-start/lib/models/list_item.dart index 726d08b3..f4e10ccd 100644 --- a/009-realtime-feedback-app/001-start/lib/models/list_item.dart +++ b/009-realtime-feedback-app/001-start/lib/models/list_item.dart @@ -1,6 +1,6 @@ -class ListItem { - final String title; - final String description; - - ListItem({this.title, this.description}); +class ListItem { + final String title; + final String description; + + ListItem({this.title, this.description}); } \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/lib/models/stats.dart b/009-realtime-feedback-app/001-start/lib/models/stats.dart index beb91194..cc070958 100644 --- a/009-realtime-feedback-app/001-start/lib/models/stats.dart +++ b/009-realtime-feedback-app/001-start/lib/models/stats.dart @@ -1,14 +1,14 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -class Stats { - final int userCount; - final int appCount; - final int errorCount; - - Stats({this.userCount, this.appCount, this.errorCount}); - - Stats.fromSnapshot(DocumentSnapshot snapShot) : - appCount = snapShot['appCount'] ?? 0, - userCount = snapShot['userCount'] ?? 0, - errorCount = snapShot['errorCount'] ?? 0; +import 'package:cloud_firestore/cloud_firestore.dart'; + +class Stats { + final int userCount; + final int appCount; + final int errorCount; + + Stats({this.userCount, this.appCount, this.errorCount}); + + Stats.fromSnapshot(DocumentSnapshot snapShot) : + appCount = snapShot['appCount'] ?? 0, + userCount = snapShot['userCount'] ?? 0, + errorCount = snapShot['errorCount'] ?? 0; } \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/lib/models/user.dart b/009-realtime-feedback-app/001-start/lib/models/user.dart index 7b050e50..6beb5a25 100644 --- a/009-realtime-feedback-app/001-start/lib/models/user.dart +++ b/009-realtime-feedback-app/001-start/lib/models/user.dart @@ -1,14 +1,14 @@ -class User { - final String username; - final String email; - final String userId; - final String accessToken; - - User({this.username, this.email, this.userId, this.accessToken}); - - User.fromJson(Map data) - : username = data['username'], - email = data['email'], - userId = data['userId'], - accessToken = data['accessToken']; -} +class User { + final String username; + final String email; + final String userId; + final String accessToken; + + User({this.username, this.email, this.userId, this.accessToken}); + + User.fromJson(Map data) + : username = data['username'], + email = data['email'], + userId = data['userId'], + accessToken = data['accessToken']; +} diff --git a/009-realtime-feedback-app/001-start/lib/scoped_models/base_model.dart b/009-realtime-feedback-app/001-start/lib/scoped_models/base_model.dart index c66dd850..edee34fa 100644 --- a/009-realtime-feedback-app/001-start/lib/scoped_models/base_model.dart +++ b/009-realtime-feedback-app/001-start/lib/scoped_models/base_model.dart @@ -1,17 +1,17 @@ -import 'package:scoped_model/scoped_model.dart'; - -import 'package:skeleton_watcher/enums/view_state.dart'; -// Make sure state enum is accessible in all inherting models -export 'package:skeleton_watcher/enums/view_state.dart'; - -class BaseModel extends Model { - ViewState _state = ViewState.Idle; - ViewState get state => _state; - - void setState(ViewState newState) { - _state = newState; - - // Notify listeners will only update listeners of state. - notifyListeners(); - } -} +import 'package:scoped_model/scoped_model.dart'; + +import 'package:skeleton_watcher/enums/view_state.dart'; +// Make sure state enum is accessible in all inherting models +export 'package:skeleton_watcher/enums/view_state.dart'; + +class BaseModel extends Model { + ViewState _state = ViewState.Idle; + ViewState get state => _state; + + void setState(ViewState newState) { + _state = newState; + + // Notify listeners will only update listeners of state. + notifyListeners(); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/scoped_models/feedback_view_model.dart b/009-realtime-feedback-app/001-start/lib/scoped_models/feedback_view_model.dart index 3a9c6ff8..e1a79020 100644 --- a/009-realtime-feedback-app/001-start/lib/scoped_models/feedback_view_model.dart +++ b/009-realtime-feedback-app/001-start/lib/scoped_models/feedback_view_model.dart @@ -1,28 +1,27 @@ -import 'package:skeleton_watcher/models/list_item.dart'; -import 'base_model.dart'; - -export 'package:skeleton_watcher/enums/view_state.dart'; - -/// Contains logic for a list view with the general expected functionality. -class FeedbackViewModel extends BaseModel { - List listData; - - Future fetchListData() async { - setState(ViewState.Busy); - - await Future.delayed(Duration(seconds: 1)); - listData = List.generate( - 10, - (index) => ListItem( - title: 'title $index', - description: 'Description of this list Item. $index')); - - if (listData == null) { - setState(ViewState.Error); - } else { - setState(listData.length == 0 - ? ViewState.NoDataAvailable - : ViewState.DataFetched); - } - } -} +import 'package:scoped_model/scoped_model.dart'; +import 'package:skeleton_watcher/models/list_item.dart'; +import 'base_model.dart'; + +export 'package:skeleton_watcher/enums/view_state.dart'; + + +/// Contains logic for a list view with the general expected functionality. +class FeedbackViewModel extends BaseModel { + List listData; + + Future fetchListData() async { + setState(ViewState.Busy); + + await Future.delayed(Duration(seconds: 1)); + listData = List.generate(10, (index) => + ListItem(title: 'title $index', description: 'Description of this list Item. $index')); + + if (listData == null) { + setState(ViewState.Error); + } else { + setState(listData.length == 0 + ? ViewState.NoDataAvailable + : ViewState.DataFetched); + } + } +} \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/lib/scoped_models/home_view_model.dart b/009-realtime-feedback-app/001-start/lib/scoped_models/home_view_model.dart index 43e38db2..fcd7c199 100644 --- a/009-realtime-feedback-app/001-start/lib/scoped_models/home_view_model.dart +++ b/009-realtime-feedback-app/001-start/lib/scoped_models/home_view_model.dart @@ -1,25 +1,25 @@ -import 'package:skeleton_watcher/models/stats.dart'; -import 'package:skeleton_watcher/service_locator.dart'; -import 'package:skeleton_watcher/services/firebase_service.dart'; - -import 'base_model.dart'; - -class HomeViewModel extends BaseModel { - FirebaseService _firebaseService = locator(); - Stats appStats; - - HomeViewModel() { - _firebaseService.appStats.listen(_onStatsUpdated); - } - - void _onStatsUpdated(Stats stats) { - appStats = stats; // Set the stats for the UI - - if (stats == null) { - setState(ViewState.Busy); // If null indicate we're still fetching - } else { - setState(ViewState - .DataFetched); // When not null indicate that the data is fetched - } - } -} +import 'package:skeleton_watcher/models/stats.dart'; +import 'package:skeleton_watcher/service_locator.dart'; +import 'package:skeleton_watcher/services/firebase_service.dart'; + +import 'base_model.dart'; + +class HomeViewModel extends BaseModel { + FirebaseService _firebaseService = locator(); + Stats appStats; + + HomeViewModel() { + _firebaseService.appStats.listen(_onStatsUpdated); + } + + void _onStatsUpdated(Stats stats) { + appStats = stats; // Set the stats for the UI + + if (stats == null) { + setState(ViewState.Busy); // If null indicate we're still fetching + } else { + setState(ViewState + .DataFetched); // When not null indicate that the data is fetched + } + } +} diff --git a/009-realtime-feedback-app/001-start/lib/service_locator.dart b/009-realtime-feedback-app/001-start/lib/service_locator.dart index 46cf324e..aec830bc 100644 --- a/009-realtime-feedback-app/001-start/lib/service_locator.dart +++ b/009-realtime-feedback-app/001-start/lib/service_locator.dart @@ -1,15 +1,16 @@ -import 'package:get_it/get_it.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; -import 'package:skeleton_watcher/services/firebase_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - // Register services - locator.registerLazySingleton(() => FirebaseService()); - - // Register ScopedModels - locator.registerFactory(() => HomeViewModel()); - locator.registerFactory(() => FeedbackViewModel()); -} +import 'package:get_it/get_it.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; +import 'package:skeleton_watcher/services/firebase_service.dart'; + +GetIt locator = new GetIt(); + +void setupLocator() { + // Register services + locator.registerLazySingleton(() => FirebaseService()); + + // Register ScopedModels + locator.registerFactory(() => HomeViewModel()); + locator.registerFactory(() => FeedbackViewModel()); +} + diff --git a/009-realtime-feedback-app/001-start/lib/services/firebase_service.dart b/009-realtime-feedback-app/001-start/lib/services/firebase_service.dart index fa40732c..d8340374 100644 --- a/009-realtime-feedback-app/001-start/lib/services/firebase_service.dart +++ b/009-realtime-feedback-app/001-start/lib/services/firebase_service.dart @@ -1,22 +1,22 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:skeleton_watcher/models/stats.dart'; - -class FirebaseService { - final StreamController _statsController = StreamController(); - - FirebaseService() { - Firestore.instance - .collection('informations') - .document('project_stats') - .snapshots() - .listen(_statsUpdated); - } - - Stream get appStats => _statsController.stream; - - void _statsUpdated(DocumentSnapshot snapshot) { - _statsController.add(Stats.fromSnapshot(snapshot)); - } -} +import 'dart:async'; + +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:skeleton_watcher/models/stats.dart'; + +class FirebaseService { + final StreamController _statsController = StreamController(); + + FirebaseService() { + Firestore.instance + .collection('informations') + .document('project_stats') + .snapshots() + .listen(_statsUpdated); + } + + Stream get appStats => _statsController.stream; + + void _statsUpdated(DocumentSnapshot snapshot) { + _statsController.add(Stats.fromSnapshot(snapshot)); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/shared/app_colors.dart b/009-realtime-feedback-app/001-start/lib/ui/shared/app_colors.dart index e5ca3a2c..d976c11e 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/shared/app_colors.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/shared/app_colors.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); +import 'package:flutter/material.dart'; + +const Color lightGrey = Color.fromARGB(255,61,63,69); +const Color darkGrey = Color.fromARGB(255,18,18,19); +const Color primaryColor = Color.fromARGB(255, 9, 202, 172); +const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/009-realtime-feedback-app/001-start/lib/ui/shared/font_styles.dart b/009-realtime-feedback-app/001-start/lib/ui/shared/font_styles.dart index d224f955..bed44618 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/shared/font_styles.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/shared/font_styles.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); const TextStyle viewErrorTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800, color: lightGrey); \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/lib/ui/shared/ui_helpers.dart b/009-realtime-feedback-app/001-start/lib/ui/shared/ui_helpers.dart index 8665bf7c..390780a6 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/shared/ui_helpers.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/shared/ui_helpers.dart @@ -1,114 +1,114 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 20.0; - static const double _VerticalSpaceMedium = 40.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 20.0; - static const double _HorizontalSpaceMedium = 40.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } - - /// Provides an input field with a title that stretches the full width of the screen - static Widget inputField({ - String title, - String placeholder, - @required TextEditingController controller, - String validationMessage, - bool isPassword = false, - double spaceBetweenTitle = 15.0, - double padding = 10.0}) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), - validationMessage != null ? Text( - validationMessage, - style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), - Container( - alignment: Alignment(0.0, 0.0), - padding: EdgeInsets.only(left: padding), - margin: EdgeInsets.only(top: spaceBetweenTitle), - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: lightGrey - ), - child: TextField( - controller: controller, - obscureText: isPassword, - style: TextStyle(fontSize: 12.0), - decoration: InputDecoration.collapsed( - hintText: placeholder, - hintStyle: - TextStyle(color: Colors.grey[600], fontSize: 12.0)), - ), - ) - ]); - } - - static Widget fullScreenButton({ - String title, - Function onTap - }) { - return GestureDetector( - onTap: onTap , - child: Container( - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Color.fromARGB(255, 9, 202, 172)), - child: Center( - child: - Text(title, style: TextStyle(fontWeight: FontWeight.w800))), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +/// Contains useful functions to reduce boilerplate code +class UIHelper { + // Vertical spacing constants. Adjust to your liking. + static const double _VerticalSpaceSmall = 20.0; + static const double _VerticalSpaceMedium = 40.0; + static const double _VerticalSpaceLarge = 60.0; + + // Vertical spacing constants. Adjust to your liking. + static const double _HorizontalSpaceSmall = 20.0; + static const double _HorizontalSpaceMedium = 40.0; + static const double HorizontalSpaceLarge = 60.0; + + /// Returns a vertical space with height set to [_VerticalSpaceSmall] + static Widget verticalSpaceSmall() { + return verticalSpace(_VerticalSpaceSmall); + } + + /// Returns a vertical space with height set to [_VerticalSpaceMedium] + static Widget verticalSpaceMedium() { + return verticalSpace(_VerticalSpaceMedium); + } + + /// Returns a vertical space with height set to [_VerticalSpaceLarge] + static Widget verticalSpaceLarge() { + return verticalSpace(_VerticalSpaceLarge); + } + + /// Returns a vertical space equal to the [height] supplied + static Widget verticalSpace(double height) { + return Container(height: height); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceSmall] + static Widget horizontalSpaceSmall() { + return horizontalSpace(_HorizontalSpaceSmall); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceMedium] + static Widget horizontalSpaceMedium() { + return horizontalSpace(_HorizontalSpaceMedium); + } + + /// Returns a vertical space with height set to [HorizontalSpaceLarge] + static Widget horizontalSpaceLarge() { + return horizontalSpace(HorizontalSpaceLarge); + } + + /// Returns a vertical space equal to the [width] supplied + static Widget horizontalSpace(double width) { + return Container(width: width); + } + + /// Provides an input field with a title that stretches the full width of the screen + static Widget inputField({ + String title, + String placeholder, + @required TextEditingController controller, + String validationMessage, + bool isPassword = false, + double spaceBetweenTitle = 15.0, + double padding = 10.0}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, + style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), + validationMessage != null ? Text( + validationMessage, + style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), + Container( + alignment: Alignment(0.0, 0.0), + padding: EdgeInsets.only(left: padding), + margin: EdgeInsets.only(top: spaceBetweenTitle), + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: lightGrey + ), + child: TextField( + controller: controller, + obscureText: isPassword, + style: TextStyle(fontSize: 12.0), + decoration: InputDecoration.collapsed( + hintText: placeholder, + hintStyle: + TextStyle(color: Colors.grey[600], fontSize: 12.0)), + ), + ) + ]); + } + + static Widget fullScreenButton({ + String title, + Function onTap + }) { + return GestureDetector( + onTap: onTap , + child: Container( + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: Color.fromARGB(255, 9, 202, 172)), + child: Center( + child: + Text(title, style: TextStyle(fontWeight: FontWeight.w800))), + ), + ); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/shared/ui_reducers.dart b/009-realtime-feedback-app/001-start/lib/ui/shared/ui_reducers.dart index 54c9c712..0e8b0fb4 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/shared/ui_reducers.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/shared/ui_reducers.dart @@ -1,7 +1,7 @@ -import 'package:flutter/widgets.dart'; - -double screenHeight(BuildContext context, - {int dividedBy = 1, double decreasedBy = 0.0}) { - assert(dividedBy != 0, "Don't divide by 0"); - return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; -} +import 'package:flutter/widgets.dart'; + +double screenHeight(BuildContext context, + {int dividedBy = 1, double decreasedBy = 0.0}) { + assert(dividedBy != 0, "Don't divide by 0"); + return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/views/base_view.dart b/009-realtime-feedback-app/001-start/lib/ui/views/base_view.dart index 042f5f47..dcda33b3 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/views/base_view.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/views/base_view.dart @@ -1,40 +1,40 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_model/scoped_model.dart'; -import 'package:skeleton_watcher/service_locator.dart'; - -class BaseView extends StatefulWidget { - - final ScopedModelDescendantBuilder _builder; - - /// Function will be called as soon as the widget is initialised. - /// - /// Callback will reive the model that was created and supplied to the ScopedModel - final Function(T) onModelReady; - - BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) - : _builder = builder; - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T _model = locator(); - - @override - void initState() { - if(widget.onModelReady != null) { - widget.onModelReady(_model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ScopedModel( - model: _model, - child: ScopedModelDescendant( - child: Container(color: Colors.red), - builder: widget._builder)); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:skeleton_watcher/service_locator.dart'; + +class BaseView extends StatefulWidget { + + final ScopedModelDescendantBuilder _builder; + + /// Function will be called as soon as the widget is initialised. + /// + /// Callback will reive the model that was created and supplied to the ScopedModel + final Function(T) onModelReady; + + BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) + : _builder = builder; + + @override + _BaseViewState createState() => _BaseViewState(); +} + +class _BaseViewState extends State> { + T _model = locator(); + + @override + void initState() { + if(widget.onModelReady != null) { + widget.onModelReady(_model); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ScopedModel( + model: _model, + child: ScopedModelDescendant( + child: Container(color: Colors.red), + builder: widget._builder)); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/views/feedback_view.dart b/009-realtime-feedback-app/001-start/lib/ui/views/feedback_view.dart index 8abadc60..d0660247 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/views/feedback_view.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/views/feedback_view.dart @@ -1,109 +1,109 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/models/list_item.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; -import 'package:skeleton_watcher/ui/shared/font_styles.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; - -class FeedbackView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.fetchListData(), - builder: (context, childe, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: Container(child: _getBodyUi(context, model)))); - } - - Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { - switch (model.state) { - case ViewState.Busy: - return _getLoadingUi(context); - case ViewState.NoDataAvailable: - return _noDataUi(context, model); - case ViewState.Error: - return _errorUi(context, model); - case ViewState.DataFetched: - default: - return _getListUi(model); - } - } - - Widget _getListUi(FeedbackViewModel model) { - return ListView.builder( - itemCount: model.listData.length, - itemBuilder: (context, itemIndex) { - var item = model.listData[itemIndex]; - return _getListItemUi(item); - }); - } - - Container _getListItemUi(ListItem result) { - return Container( - height: 100.0, - margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: lightGrey), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text(result.title, style: viewTitle), - Text(result.description) - ], - ), - ); - } - - Widget _getLoadingUi(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator( - valueColor: - AlwaysStoppedAnimation(Theme.of(context).primaryColor)), - Text('Fetching data ...') - ], - )); - } - - Widget _noDataUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage( - context, - "No data available yet", - model); - } - - Widget _errorUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage( - context, - "Error retrieving your data. Tap to try again", - model, - error: true); - } - - Widget _getCenteredViewMessage( - BuildContext context, String message, FeedbackViewModel model, - {bool error = false}) { - return Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - message, - style: viewErrorTitle, - textAlign: TextAlign.center, - ), - error - ? Icon( // WWrap in gesture detector and call you refresh future here - Icons.refresh, - color: Colors.white, - size: 45.0, - ) - : Container() - ], - ))); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/models/list_item.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; +import 'package:skeleton_watcher/ui/shared/font_styles.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; + +class FeedbackView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.fetchListData(), + builder: (context, childe, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: Container(child: _getBodyUi(context, model)))); + } + + Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { + switch (model.state) { + case ViewState.Busy: + return _getLoadingUi(context); + case ViewState.NoDataAvailable: + return _noDataUi(context, model); + case ViewState.Error: + return _errorUi(context, model); + case ViewState.DataFetched: + default: + return _getListUi(model); + } + } + + Widget _getListUi(FeedbackViewModel model) { + return ListView.builder( + itemCount: model.listData.length, + itemBuilder: (context, itemIndex) { + var item = model.listData[itemIndex]; + return _getListItemUi(item); + }); + } + + Container _getListItemUi(ListItem result) { + return Container( + height: 100.0, + margin: EdgeInsets.symmetric(horizontal: 10.0, vertical: 5.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: lightGrey), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text(result.title, style: viewTitle), + Text(result.description) + ], + ), + ); + } + + Widget _getLoadingUi(BuildContext context) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation(Theme.of(context).primaryColor)), + Text('Fetching data ...') + ], + )); + } + + Widget _noDataUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage( + context, + "No data available yet", + model); + } + + Widget _errorUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage( + context, + "Error retrieving your data. Tap to try again", + model, + error: true); + } + + Widget _getCenteredViewMessage( + BuildContext context, String message, FeedbackViewModel model, + {bool error = false}) { + return Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + message, + style: viewErrorTitle, + textAlign: TextAlign.center, + ), + error + ? Icon( // WWrap in gesture detector and call you refresh future here + Icons.refresh, + color: Colors.white, + size: 45.0, + ) + : Container() + ], + ))); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/views/home_view.dart b/009-realtime-feedback-app/001-start/lib/ui/views/home_view.dart index 709898a0..b1f89416 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/views/home_view.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/views/home_view.dart @@ -1,92 +1,92 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/enums/view_state.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; -import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; -import 'package:skeleton_watcher/ui/views/feedback_view.dart'; -import 'package:skeleton_watcher/ui/widgets/indicator_button.dart'; -import 'package:skeleton_watcher/ui/widgets/stats_counter.dart'; -import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; - -class HomeView extends StatelessWidget { - static const BoxDecoration topLineBorderDecoration = BoxDecoration( - border: Border( - top: BorderSide( - color: lightGrey, style: BorderStyle.solid, width: 5.0))); - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, child, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: _getBody(model, context))); - } - - Widget _getBody(HomeViewModel model, BuildContext context) { - switch (model.state) { - case ViewState.Busy: - case ViewState.Idle: - return Center(child: CircularProgressIndicator()); - default: - return _getStatsUi(model, context); - } - } - - Widget _getStatsUi(HomeViewModel model, BuildContext context) { - return Column(children: [ - WatcherToolbar(title: 'SKELETON-WATCHER'), - _getHeightContainer( - context: context, - height: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), - child: StatsCounter( - size: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight) - 60, // 60 margins - count: model.appStats.errorCount, - title: 'Errors', - titleColor: Colors.red, - ), - ), - _getHeightContainer( - context: context, - height:screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - StatsCounter( - size: screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight) - 60, - count: model.appStats.userCount, - title: 'Users', - ), - StatsCounter( - size: screenHeight(context,dividedBy: 3, decreasedBy: toolbarHeight) - 60, - count: model.appStats.appCount, - title: 'Apps Created', - ) - ]) - ), - _getHeightContainer( - height:screenHeight(context, dividedBy: 6, decreasedBy: toolbarHeight), - child: IndicatorButton( - title: 'FEEDBACK', - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => FeedbackView())); - } - )) - ]); - } - - Widget _getHeightContainer( - {double height, - BuildContext context, - Widget child, - bool hasTopStroke = false}) { - return Container( - height: height, - alignment: Alignment.center, - margin: EdgeInsets.symmetric(horizontal: 20.0), - decoration: hasTopStroke? topLineBorderDecoration : null, - child: child); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/enums/view_state.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; +import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; +import 'package:skeleton_watcher/ui/views/feedback_view.dart'; +import 'package:skeleton_watcher/ui/widgets/indicator_button.dart'; +import 'package:skeleton_watcher/ui/widgets/stats_counter.dart'; +import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; + +class HomeView extends StatelessWidget { + static const BoxDecoration topLineBorderDecoration = BoxDecoration( + border: Border( + top: BorderSide( + color: lightGrey, style: BorderStyle.solid, width: 5.0))); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, child, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: _getBody(model, context))); + } + + Widget _getBody(HomeViewModel model, BuildContext context) { + switch (model.state) { + case ViewState.Busy: + case ViewState.Idle: + return Center(child: CircularProgressIndicator()); + default: + return _getStatsUi(model, context); + } + } + + Widget _getStatsUi(HomeViewModel model, BuildContext context) { + return Column(children: [ + WatcherToolbar(title: 'SKELETON-WATCHER'), + _getHeightContainer( + context: context, + height: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), + child: StatsCounter( + size: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight) - 60, // 60 margins + count: model.appStats.errorCount, + title: 'Errors', + titleColor: Colors.red, + ), + ), + _getHeightContainer( + context: context, + height:screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + StatsCounter( + size: screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight) - 60, + count: model.appStats.userCount, + title: 'Users', + ), + StatsCounter( + size: screenHeight(context,dividedBy: 3, decreasedBy: toolbarHeight) - 60, + count: model.appStats.appCount, + title: 'Apps Created', + ) + ]) + ), + _getHeightContainer( + height:screenHeight(context, dividedBy: 6, decreasedBy: toolbarHeight), + child: IndicatorButton( + title: 'FEEDBACK', + onTap: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => FeedbackView())); + } + )) + ]); + } + + Widget _getHeightContainer( + {double height, + BuildContext context, + Widget child, + bool hasTopStroke = false}) { + return Container( + height: height, + alignment: Alignment.center, + margin: EdgeInsets.symmetric(horizontal: 20.0), + decoration: hasTopStroke? topLineBorderDecoration : null, + child: child); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/widgets/busy_overlay.dart b/009-realtime-feedback-app/001-start/lib/ui/widgets/busy_overlay.dart index 24f0f4b6..f2617207 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/widgets/busy_overlay.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/widgets/busy_overlay.dart @@ -1,45 +1,45 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} +import 'package:flutter/material.dart'; + +/// A modal overlay that will show over your child widget (fullscreen) when the show value is true +/// +/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when +/// your model state is Busy +class BusyOverlay extends StatelessWidget { + final Widget child; + final String title; + final bool show; + + const BusyOverlay({this.child, + this.title = 'Please wait...', + this.show = false}); + + @override + Widget build(BuildContext context) { + var screenSize = MediaQuery.of(context).size; + return Material( + child: Stack(children: [ + child, + IgnorePointer( + child: Opacity( + opacity: show ? 1.0 : 0.0, + child: Container( + width: screenSize.width, + height: screenSize.height, + alignment: Alignment.center, + color: Color.fromARGB(100, 0, 0, 0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(), + Text(title, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + )), + ), + ])); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/widgets/indicator_button.dart b/009-realtime-feedback-app/001-start/lib/ui/widgets/indicator_button.dart index 6cb88f6b..d617fe2a 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/widgets/indicator_button.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/widgets/indicator_button.dart @@ -1,47 +1,47 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -class IndicatorButton extends StatelessWidget { - final double height; - final String title; - final Function onTap; - final int indicationCount; - - const IndicatorButton({this.height = 50.0, this.title, this.onTap, this.indicationCount}); - - bool get hasIndication => indicationCount != null && indicationCount > 0; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - height: height, - child: Stack(children: [ - Container( - height: height, - width: double.infinity, - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: primaryColor), - child: Text( - title, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), - )), - hasIndication ? Positioned( - top: 10, - right: 20.0, - child: Container( - width: 30, - height: 30, - alignment: Alignment.center, - decoration: - ShapeDecoration(shape: CircleBorder(), color: darkGrey), - child: Text(indicationCount.toString(), - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400)), - ), - ) : Container() - ]), - )); - } +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +class IndicatorButton extends StatelessWidget { + final double height; + final String title; + final Function onTap; + final int indicationCount; + + const IndicatorButton({this.height = 50.0, this.title, this.onTap, this.indicationCount}); + + bool get hasIndication => indicationCount != null && indicationCount > 0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + height: height, + child: Stack(children: [ + Container( + height: height, + width: double.infinity, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: primaryColor), + child: Text( + title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), + )), + hasIndication ? Positioned( + top: 10, + right: 20.0, + child: Container( + width: 30, + height: 30, + alignment: Alignment.center, + decoration: + ShapeDecoration(shape: CircleBorder(), color: darkGrey), + child: Text(indicationCount.toString(), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400)), + ), + ) : Container() + ]), + )); + } } \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/lib/ui/widgets/stats_counter.dart b/009-realtime-feedback-app/001-start/lib/ui/widgets/stats_counter.dart index 5d4c38e3..33532d5b 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/widgets/stats_counter.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/widgets/stats_counter.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -class StatsCounter extends StatelessWidget { - final double size; - final int count; - final String title; - final Color titleColor; - - StatsCounter( - {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); - - @override - Widget build(BuildContext context) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: darkGrey), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text(count.toString(), - textAlign: TextAlign.center, - style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), - Text(title, - textAlign: TextAlign.center, - style: TextStyle( - color: titleColor, - fontSize: size * 0.1, fontWeight: FontWeight.w400)) - ]), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +class StatsCounter extends StatelessWidget { + final double size; + final int count; + final String title; + final Color titleColor; + + StatsCounter( + {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); + + @override + Widget build(BuildContext context) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: darkGrey), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(count.toString(), + textAlign: TextAlign.center, + style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), + Text(title, + textAlign: TextAlign.center, + style: TextStyle( + color: titleColor, + fontSize: size * 0.1, fontWeight: FontWeight.w400)) + ]), + ); + } +} diff --git a/009-realtime-feedback-app/001-start/lib/ui/widgets/watcher_toolbar.dart b/009-realtime-feedback-app/001-start/lib/ui/widgets/watcher_toolbar.dart index afaf138d..8161765e 100644 --- a/009-realtime-feedback-app/001-start/lib/ui/widgets/watcher_toolbar.dart +++ b/009-realtime-feedback-app/001-start/lib/ui/widgets/watcher_toolbar.dart @@ -1,38 +1,38 @@ -import 'package:flutter/material.dart'; - -const double toolbarHeight = 80.0; - -class WatcherToolbar extends StatelessWidget { - final String title; - final bool showBackButton; - const WatcherToolbar({@required this.title, this.showBackButton = false}); - - @override - Widget build(BuildContext context) { - return Container( - height: toolbarHeight, - margin: EdgeInsets.symmetric(horizontal: 20.0), - child: Row( - children: [ - showBackButton - ? GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.centerLeft, - width: 50, - child: Icon(Icons.chevron_left, - size: 30, color: Colors.white)), - ) - : Container(), - Expanded( - child: Text(title, - textAlign: TextAlign.right, - style: TextStyle(fontWeight: FontWeight.w800)), - ), - ], - ), - ); - } +import 'package:flutter/material.dart'; + +const double toolbarHeight = 80.0; + +class WatcherToolbar extends StatelessWidget { + final String title; + final bool showBackButton; + const WatcherToolbar({@required this.title, this.showBackButton = false}); + + @override + Widget build(BuildContext context) { + return Container( + height: toolbarHeight, + margin: EdgeInsets.symmetric(horizontal: 20.0), + child: Row( + children: [ + showBackButton + ? GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Container( + alignment: Alignment.centerLeft, + width: 50, + child: Icon(Icons.chevron_left, + size: 30, color: Colors.white)), + ) + : Container(), + Expanded( + child: Text(title, + textAlign: TextAlign.right, + style: TextStyle(fontWeight: FontWeight.w800)), + ), + ], + ), + ); + } } \ No newline at end of file diff --git a/009-realtime-feedback-app/001-start/pubspec.lock b/009-realtime-feedback-app/001-start/pubspec.lock index 6afbe482..10d0e190 100644 --- a/009-realtime-feedback-app/001-start/pubspec.lock +++ b/009-realtime-feedback-app/001-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,28 +7,21 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.2.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" cloud_firestore: dependency: "direct main" description: @@ -42,21 +35,14 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" firebase_core: dependency: transitive description: @@ -80,28 +66,42 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "1.0.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" scoped_model: dependency: "direct main" description: @@ -120,7 +120,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -155,7 +155,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.5" typed_data: dependency: transitive description: @@ -171,5 +171,5 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" flutter: ">=1.2.0 <2.0.0" diff --git a/009-realtime-feedback-app/001-start/pubspec.yaml b/009-realtime-feedback-app/001-start/pubspec.yaml index 4ab6d96d..b9aafeca 100644 --- a/009-realtime-feedback-app/001-start/pubspec.yaml +++ b/009-realtime-feedback-app/001-start/pubspec.yaml @@ -1,76 +1,78 @@ -name: skeleton_watcher -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # scoped model packages - scoped_model: ^1.0.1 - # get it - get_it: ^4.0.2 - # firebase firestore - cloud_firestore: - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: skeleton_watcher +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + # scoped model packages + scoped_model: ^1.0.1 + # get it + get_it: ^1.0.3 + # firebase firestore + cloud_firestore: + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: Open Sans + fonts: + - asset: assets/fonts/OpenSans-Bold.ttf + weight: 700 + - asset: assets/fonts/OpenSans-ExtraBold.ttf + weight: 800 + - asset: assets/fonts/OpenSans-Light.ttf + weight: 300 + - asset: assets/fonts/OpenSans-Regular.ttf + weight: 400 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/009-realtime-feedback-app/001-start/test/widget_test.dart b/009-realtime-feedback-app/001-start/test/widget_test.dart index ee9c85de..688c5230 100644 --- a/009-realtime-feedback-app/001-start/test/widget_test.dart +++ b/009-realtime-feedback-app/001-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:skeleton_watcher/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:skeleton_watcher/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/009-realtime-feedback-app/002-final/.flutter-plugins-dependencies b/009-realtime-feedback-app/002-final/.flutter-plugins-dependencies deleted file mode 100644 index db1560da..00000000 --- a/009-realtime-feedback-app/002-final/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.10.0/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.3.4/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.10.0/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.3.4/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core"]},{"name":"firebase_core","dependencies":[]}],"date_created":"2020-06-18 21:49:00.278249","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/.gitignore b/009-realtime-feedback-app/002-final/.gitignore index 5be59a14..07488ba6 100644 --- a/009-realtime-feedback-app/002-final/.gitignore +++ b/009-realtime-feedback-app/002-final/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/009-realtime-feedback-app/002-final/.metadata b/009-realtime-feedback-app/002-final/.metadata index 0012359c..32e51230 100644 --- a/009-realtime-feedback-app/002-final/.metadata +++ b/009-realtime-feedback-app/002-final/.metadata @@ -1,10 +1,10 @@ -# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app +# 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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff + channel: master + +project_type: app diff --git a/009-realtime-feedback-app/002-final/README.md b/009-realtime-feedback-app/002-final/README.md index 9b0e6f2b..e2a9cf07 100644 --- a/009-realtime-feedback-app/002-final/README.md +++ b/009-realtime-feedback-app/002-final/README.md @@ -1,82 +1,82 @@ -# Flutter using AppSkeletons - ScopedModel architecture - -This project has been generated with [AppSkeletons](https://www.appskeletons.com). - -This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. - -ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. - -### About this template - -There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. - -#### One AppModel with FeatureModel mixins -In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. - -**Pros:** - - State is managed in one place (and all the benefits of that). - - All functionality is Easily accessible from one model using inherited widget functionality. - - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. - -**Cons:** - - notifyListeners can have multiple bindings alive at any point. - - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. - - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. - -#### One Model per view - -**Pros:** - - View has it's own dedicated Model - - All state functionality and reduction for a view is contained in it's own Model - - Better logical and mental grouping (View + View's Model) - -**Cons:** - - More Models to be aware of and manage - - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) - - Harder to make use of Logic from other models (which should never happen anyway) - -I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. - -### The implementation - -This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. - -Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. - -## Getting Started - -1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. -2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio -3. Run application - -## Structure and placement - -The root folder is split into 4 sections, models, scoped_models, services and ui. - -### Models - -Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. - -### Scoped Models - -In this scoped_models folder you'll place all the models associated with your views. One per view. - -**Naming convention:** [viewname]_model.dart i.e. home_model.dart - -### Services - -This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. - -**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart - -### UI - -Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. - -**views/**: Contains the files for each of the views in your applications. - -Naming convention: [viewname]_view.dart - -## Conclusion - +# Flutter using AppSkeletons - ScopedModel architecture + +This project has been generated with [AppSkeletons](https://www.appskeletons.com). + +This project serves as a starting point and guideline for how to develop a production application in Flutter using the ScopeModel architecture. This architecture can be implemented in more than one way, but this is the way we found it to work best for long term code health. + +ScopedModel is not a pattern for large apps, but using it this way you can push the limits of what you can achieve in terms on the size of your apps. + +### About this template + +There are two mind sets when creating an app using ScopedModel, that I've seen. In both of these the actual work is delegated to services. The model just uses services and it's functionality to produce the correct state for the app UI based on the user's interactions. + +#### One AppModel with FeatureModel mixins +In this way you have one AppModel that extends Mixins, that are also of type Model but groups certain functionality together. UserModel, AuthenticationModel, InformationModel, etc. You pass the combined one AppModel from the top of your application widget tree and access it anywhere in the app using the ScopedModelDescendent. + +**Pros:** + - State is managed in one place (and all the benefits of that). + - All functionality is Easily accessible from one model using inherited widget functionality. + - Combining multiple functionalities can be done in the Main AppModel class since all feature models functionalities are available through the mixins. + +**Cons:** + - notifyListeners can have multiple bindings alive at any point. + - All state is reduced per view without any clear indication inside the model which parts of the state is there for a specific view. + - View specific models has to keep a reference to the main AppModel incase of custom view only state functionality. Like views that have 3 different internal states for different UI. + +#### One Model per view + +**Pros:** + - View has it's own dedicated Model + - All state functionality and reduction for a view is contained in it's own Model + - Better logical and mental grouping (View + View's Model) + +**Cons:** + - More Models to be aware of and manage + - More boiler plate code when creating a new view ([appskeletons](https://www.appskeletons.com) can take care of that :) + - Harder to make use of Logic from other models (which should never happen anyway) + +I have implemented my first production Flutter app for a client using ScopedModel with the first structure I described. For this template I am now leaning towards the second one because of how mixed up the state management became having to cater for multiple views from a single feature model. + +### The implementation + +This project Starts off by registering all the services and available app models in the `service_locator.dart` file. We use [get_it](https://pub.dartlang.org/packages/get_it) for our dependenct injection. `setupLocator` is called before the application is instantiated in `main.dart` to ensure that all services area available from the locator. To use the locator anywhere import `service_locator.dart` and use locator() to get your registered instance. + +Each view has a ScopedModel at the root and gets the model from the locator. The Model's binding functionality is accessed using the ScopedModelDescendant. + +## Getting Started + +1. Make sure all the packages are fetched. Run the flutter packages get command or open Pubspec.yaml and save. +2. Go to debug tab (in Visual Code) and set configuration to Dart & Flutter. Ignore for Android Studio +3. Run application + +## Structure and placement + +The root folder is split into 4 sections, models, scoped_models, services and ui. + +### Models + +Contains all the application's data models. If multiple models belongs to certain features I recommend placing them in their own folders to keep the code clean. + +### Scoped Models + +In this scoped_models folder you'll place all the models associated with your views. One per view. + +**Naming convention:** [viewname]_model.dart i.e. home_model.dart + +### Services + +This will contain separate services that houses all the actual functionality for your app. Fetching information, caching it locally, updating the DB, all those should be separate services in here. When registering these with the service locator it's usually registered as a singleton. + +**Naming convention:** [functionality]_service.dart i.e. authentication_service.dart + +### UI + +Contains all the code relating to the user interface. Flutter is a code first approach to building UI (which is great) so all the code files can live together in harmony without having to fuss about if it's an asset or a code file like in native programming. We only have one folder (as a start) and with more code I usually introduce a components folder as well as a util folder for shared UI helper functions. The structure is as follows. + +**views/**: Contains the files for each of the views in your applications. + +Naming convention: [viewname]_view.dart + +## Conclusion + There are many other things you can setup in your app all depending on your code style. I have a full video on my [Youtube channel](https://www.youtube.com/channel/UC2d0BYlqQCdF9lJfydl_02Q) describing how to setup this template from scratch. \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/android/app/build.gradle b/009-realtime-feedback-app/002-final/android/app/build.gradle new file mode 100644 index 00000000..0e1f6e02 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/build.gradle @@ -0,0 +1,66 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.appskeletons.skeleton_watcher" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + multiDexEnabled true + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'com.google.firebase:firebase-core:16.0.1' + implementation 'com.android.support:multidex:1.0.3' +} + +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/android/app/src/debug/AndroidManifest.xml b/009-realtime-feedback-app/002-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/AndroidManifest.xml b/009-realtime-feedback-app/002-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..92f71cc8 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java b/009-realtime-feedback-app/002-final/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java new file mode 100644 index 00000000..6e695021 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/src/main/java/com/example/scoped_model_arc/MainActivity.java @@ -0,0 +1,13 @@ +package com.appskeletons.skeleton_watcher; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/drawable/launch_background.xml b/009-realtime-feedback-app/002-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..219bdbfa --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..70cde7e6 Binary files /dev/null and b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..34d76500 Binary files /dev/null and b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..03ca164d Binary files /dev/null and b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..5cbbce61 Binary files /dev/null and b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..3ce53d50 Binary files /dev/null and b/009-realtime-feedback-app/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/values/colors.xml b/009-realtime-feedback-app/002-final/android/app/src/main/res/values/colors.xml new file mode 100644 index 00000000..d88c48a0 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/src/main/res/values/colors.xml @@ -0,0 +1,4 @@ + + + #1A1B1E + \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/android/app/src/main/res/values/styles.xml b/009-realtime-feedback-app/002-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/009-realtime-feedback-app/002-final/android/app/src/profile/AndroidManifest.xml b/009-realtime-feedback-app/002-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..3632ffb6 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/009-realtime-feedback-app/002-final/android/build.gradle b/009-realtime-feedback-app/002-final/android/build.gradle new file mode 100644 index 00000000..3e107571 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/build.gradle @@ -0,0 +1,30 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + classpath 'com.google.gms:google-services:4.0.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/009-realtime-feedback-app/002-final/android/gradle.properties b/009-realtime-feedback-app/002-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/009-realtime-feedback-app/002-final/android/gradle/wrapper/gradle-wrapper.properties b/009-realtime-feedback-app/002-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/009-realtime-feedback-app/002-final/android/settings.gradle b/009-realtime-feedback-app/002-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/009-realtime-feedback-app/002-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/009-realtime-feedback-app/002-final/ios/Flutter/AppFrameworkInfo.plist b/009-realtime-feedback-app/002-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/009-realtime-feedback-app/002-final/ios/Flutter/Debug.xcconfig b/009-realtime-feedback-app/002-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/009-realtime-feedback-app/002-final/ios/Flutter/Release.xcconfig b/009-realtime-feedback-app/002-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.pbxproj b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..8f843ba4 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.appskeletons.skeletonWatcher; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/009-realtime-feedback-app/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/009-realtime-feedback-app/002-final/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 00000000..949b6789 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Original + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner/AppDelegate.h b/009-realtime-feedback-app/002-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/009-realtime-feedback-app/002-final/ios/Runner/AppDelegate.m b/009-realtime-feedback-app/002-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..5bba67f7 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..bcbf413f Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..85071a7f Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..74ca0555 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..c1ab6b62 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..645f3ea4 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..b9e95e26 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..35a779aa Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..8561e1d0 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a645edf5 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..04a5aeae Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..3010c219 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..e6be06ed Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..0e78dc08 Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/Contents.json b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 00000000..da4a164c --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json new file mode 100644 index 00000000..4605c085 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..88c28e8b Binary files /dev/null and b/009-realtime-feedback-app/002-final/ios/Runner/Assets.xcassets/SplashIcon.imageset/Icon-App-83.5x83.5@2x.png differ diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/009-realtime-feedback-app/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..5888d89e --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Base.lproj/Main.storyboard b/009-realtime-feedback-app/002-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner/Info.plist b/009-realtime-feedback-app/002-final/ios/Runner/Info.plist new file mode 100644 index 00000000..fa2050a2 --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + skeleton_watcher + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/009-realtime-feedback-app/002-final/ios/Runner/main.m b/009-realtime-feedback-app/002-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/009-realtime-feedback-app/002-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/enums/view_state.dart b/009-realtime-feedback-app/002-final/lib/enums/view_state.dart index 72c2d168..a68c220e 100644 --- a/009-realtime-feedback-app/002-final/lib/enums/view_state.dart +++ b/009-realtime-feedback-app/002-final/lib/enums/view_state.dart @@ -1,13 +1,13 @@ - -/// A value mapping the View UI to the state in the Model. -/// -/// This will contain all the possible states for any view, custom enums can be created for separate views if required -enum ViewState { - Idle, // When nothing is happening or just initialized - Busy, // Typically shows a loading indicator of some sorts - DataFetched, // Indicates that there's data available on the view - NoDataAvailable, // Indicates that data was fetched successfully but nothing is available - Error, // Indicates there's an error on the view - Success, // Successful action occurred - WaitingForInput // The starting state that a form view is in + +/// A value mapping the View UI to the state in the Model. +/// +/// This will contain all the possible states for any view, custom enums can be created for separate views if required +enum ViewState { + Idle, // When nothing is happening or just initialized + Busy, // Typically shows a loading indicator of some sorts + DataFetched, // Indicates that there's data available on the view + NoDataAvailable, // Indicates that data was fetched successfully but nothing is available + Error, // Indicates there's an error on the view + Success, // Successful action occurred + WaitingForInput // The starting state that a form view is in } \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/lib/main.dart b/009-realtime-feedback-app/002-final/lib/main.dart index 9e431cfb..6e8e5f91 100644 --- a/009-realtime-feedback-app/002-final/lib/main.dart +++ b/009-realtime-feedback-app/002-final/lib/main.dart @@ -1,26 +1,26 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/views/home_view.dart'; -import './service_locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Skeleton Watcher', - theme: ThemeData( - primaryColor: Color.fromARGB(255, 9, 202, 172), - backgroundColor: Color.fromARGB(255, 26, 27, 30), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - bodyColor: Colors.white, - displayColor: Colors.white)), - home: HomeView()); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/views/home_view.dart'; +import './service_locator.dart'; + +void main() { + // Register all the models and services before the app starts + setupLocator(); + + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Skeleton Watcher', + theme: ThemeData( + primaryColor: Color.fromARGB(255, 9, 202, 172), + backgroundColor: Color.fromARGB(255, 26, 27, 30), + textTheme: Theme.of(context).textTheme.apply( + fontFamily: 'Open Sans', + bodyColor: Colors.white, + displayColor: Colors.white)), + home: HomeView()); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/models/list_item.dart b/009-realtime-feedback-app/002-final/lib/models/list_item.dart index 726d08b3..f4e10ccd 100644 --- a/009-realtime-feedback-app/002-final/lib/models/list_item.dart +++ b/009-realtime-feedback-app/002-final/lib/models/list_item.dart @@ -1,6 +1,6 @@ -class ListItem { - final String title; - final String description; - - ListItem({this.title, this.description}); +class ListItem { + final String title; + final String description; + + ListItem({this.title, this.description}); } \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/lib/models/stats.dart b/009-realtime-feedback-app/002-final/lib/models/stats.dart index beb91194..cc070958 100644 --- a/009-realtime-feedback-app/002-final/lib/models/stats.dart +++ b/009-realtime-feedback-app/002-final/lib/models/stats.dart @@ -1,14 +1,14 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; - -class Stats { - final int userCount; - final int appCount; - final int errorCount; - - Stats({this.userCount, this.appCount, this.errorCount}); - - Stats.fromSnapshot(DocumentSnapshot snapShot) : - appCount = snapShot['appCount'] ?? 0, - userCount = snapShot['userCount'] ?? 0, - errorCount = snapShot['errorCount'] ?? 0; +import 'package:cloud_firestore/cloud_firestore.dart'; + +class Stats { + final int userCount; + final int appCount; + final int errorCount; + + Stats({this.userCount, this.appCount, this.errorCount}); + + Stats.fromSnapshot(DocumentSnapshot snapShot) : + appCount = snapShot['appCount'] ?? 0, + userCount = snapShot['userCount'] ?? 0, + errorCount = snapShot['errorCount'] ?? 0; } \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/lib/models/user.dart b/009-realtime-feedback-app/002-final/lib/models/user.dart index 7b050e50..6beb5a25 100644 --- a/009-realtime-feedback-app/002-final/lib/models/user.dart +++ b/009-realtime-feedback-app/002-final/lib/models/user.dart @@ -1,14 +1,14 @@ -class User { - final String username; - final String email; - final String userId; - final String accessToken; - - User({this.username, this.email, this.userId, this.accessToken}); - - User.fromJson(Map data) - : username = data['username'], - email = data['email'], - userId = data['userId'], - accessToken = data['accessToken']; -} +class User { + final String username; + final String email; + final String userId; + final String accessToken; + + User({this.username, this.email, this.userId, this.accessToken}); + + User.fromJson(Map data) + : username = data['username'], + email = data['email'], + userId = data['userId'], + accessToken = data['accessToken']; +} diff --git a/009-realtime-feedback-app/002-final/lib/models/user_feedback.dart b/009-realtime-feedback-app/002-final/lib/models/user_feedback.dart index 5ca563a4..0d7c8860 100644 --- a/009-realtime-feedback-app/002-final/lib/models/user_feedback.dart +++ b/009-realtime-feedback-app/002-final/lib/models/user_feedback.dart @@ -1,30 +1,30 @@ -class UserFeedback { - final String details; - final String note; - final bool open; - final bool read; - final String title; - final int type; - final String userId; - final String id; - - UserFeedback( - {this.details, - this.note, - this.open, - this.read, - this.title, - this.type, - this.userId, - this.id}); - - UserFeedback.fromData(Map data) - : details = data['details'], - note = data['note'], - open = data['open'] ?? true, - read = data['read'] ?? false, - title = data['title'], - type = data['type'] ?? 0, - userId = data['userId'], - id = data['id']; -} +class UserFeedback { + final String details; + final String note; + final bool open; + final bool read; + final String title; + final int type; + final String userId; + final String id; + + UserFeedback( + {this.details, + this.note, + this.open, + this.read, + this.title, + this.type, + this.userId, + this.id}); + + UserFeedback.fromData(Map data) + : details = data['details'], + note = data['note'], + open = data['open'] ?? true, + read = data['read'] ?? false, + title = data['title'], + type = data['type'] ?? 0, + userId = data['userId'], + id = data['id']; +} diff --git a/009-realtime-feedback-app/002-final/lib/scoped_models/base_model.dart b/009-realtime-feedback-app/002-final/lib/scoped_models/base_model.dart index c66dd850..edee34fa 100644 --- a/009-realtime-feedback-app/002-final/lib/scoped_models/base_model.dart +++ b/009-realtime-feedback-app/002-final/lib/scoped_models/base_model.dart @@ -1,17 +1,17 @@ -import 'package:scoped_model/scoped_model.dart'; - -import 'package:skeleton_watcher/enums/view_state.dart'; -// Make sure state enum is accessible in all inherting models -export 'package:skeleton_watcher/enums/view_state.dart'; - -class BaseModel extends Model { - ViewState _state = ViewState.Idle; - ViewState get state => _state; - - void setState(ViewState newState) { - _state = newState; - - // Notify listeners will only update listeners of state. - notifyListeners(); - } -} +import 'package:scoped_model/scoped_model.dart'; + +import 'package:skeleton_watcher/enums/view_state.dart'; +// Make sure state enum is accessible in all inherting models +export 'package:skeleton_watcher/enums/view_state.dart'; + +class BaseModel extends Model { + ViewState _state = ViewState.Idle; + ViewState get state => _state; + + void setState(ViewState newState) { + _state = newState; + + // Notify listeners will only update listeners of state. + notifyListeners(); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/scoped_models/feedback_view_model.dart b/009-realtime-feedback-app/002-final/lib/scoped_models/feedback_view_model.dart index 039e2f52..627880a2 100644 --- a/009-realtime-feedback-app/002-final/lib/scoped_models/feedback_view_model.dart +++ b/009-realtime-feedback-app/002-final/lib/scoped_models/feedback_view_model.dart @@ -1,33 +1,33 @@ -import 'package:meta/meta.dart'; -import 'package:skeleton_watcher/models/user_feedback.dart'; -import 'package:skeleton_watcher/services/firebase_service.dart'; -import '../service_locator.dart'; -import 'base_model.dart'; - -export 'package:skeleton_watcher/enums/view_state.dart'; - -/// Contains logic for a list view with the general expected functionality. -class FeedbackViewModel extends BaseModel { - FirebaseService _firebaseService = locator(); - List userFeedback; - - FeedbackViewModel() { - _firebaseService.feedback.listen(_onFeedbackUpdated); - } - - void markFeedbackAsRead({@required String feedbackId}){ - _firebaseService.markFeedbackAsRead(feedbackId: feedbackId); - } - - void _onFeedbackUpdated(List feedback) { - userFeedback = feedback; - - if (userFeedback == null) { - setState(ViewState.Busy); - } else { - setState(userFeedback.length == 0 - ? ViewState.NoDataAvailable - : ViewState.DataFetched); - } - } -} +import 'package:meta/meta.dart'; +import 'package:skeleton_watcher/models/user_feedback.dart'; +import 'package:skeleton_watcher/services/firebase_service.dart'; +import '../service_locator.dart'; +import 'base_model.dart'; + +export 'package:skeleton_watcher/enums/view_state.dart'; + +/// Contains logic for a list view with the general expected functionality. +class FeedbackViewModel extends BaseModel { + FirebaseService _firebaseService = locator(); + List userFeedback; + + FeedbackViewModel() { + _firebaseService.feedback.listen(_onFeedbackUpdated); + } + + void markFeedbackAsRead({@required String feedbackId}){ + _firebaseService.markFeedbackAsRead(feedbackId: feedbackId); + } + + void _onFeedbackUpdated(List feedback) { + userFeedback = feedback; + + if (userFeedback == null) { + setState(ViewState.Busy); + } else { + setState(userFeedback.length == 0 + ? ViewState.NoDataAvailable + : ViewState.DataFetched); + } + } +} diff --git a/009-realtime-feedback-app/002-final/lib/scoped_models/home_view_model.dart b/009-realtime-feedback-app/002-final/lib/scoped_models/home_view_model.dart index 2e2a7f4b..d582ba05 100644 --- a/009-realtime-feedback-app/002-final/lib/scoped_models/home_view_model.dart +++ b/009-realtime-feedback-app/002-final/lib/scoped_models/home_view_model.dart @@ -1,32 +1,32 @@ -import 'package:skeleton_watcher/models/stats.dart'; -import 'package:skeleton_watcher/service_locator.dart'; -import 'package:skeleton_watcher/services/firebase_service.dart'; - -import 'base_model.dart'; - -class HomeViewModel extends BaseModel { - FirebaseService _firebaseService = locator(); - Stats appStats; - int unreadCount; - - HomeViewModel() { - _firebaseService.appStats.listen(_onStatsUpdated); - _firebaseService.unreadCount.listen(_onUnreadCountUpdated); - } - - void _onStatsUpdated(Stats stats) { - appStats = stats; // Set the stats for the UI - - if (stats == null) { - setState(ViewState.Busy); // If null indicate we're still fetching - } else { - setState(ViewState - .DataFetched); // When not null indicate that the data is fetched - } - } - - void _onUnreadCountUpdated(int count) { - unreadCount = count; - setState(ViewState.DataFetched); - } -} +import 'package:skeleton_watcher/models/stats.dart'; +import 'package:skeleton_watcher/service_locator.dart'; +import 'package:skeleton_watcher/services/firebase_service.dart'; + +import 'base_model.dart'; + +class HomeViewModel extends BaseModel { + FirebaseService _firebaseService = locator(); + Stats appStats; + int unreadCount; + + HomeViewModel() { + _firebaseService.appStats.listen(_onStatsUpdated); + _firebaseService.unreadCount.listen(_onUnreadCountUpdated); + } + + void _onStatsUpdated(Stats stats) { + appStats = stats; // Set the stats for the UI + + if (stats == null) { + setState(ViewState.Busy); // If null indicate we're still fetching + } else { + setState(ViewState + .DataFetched); // When not null indicate that the data is fetched + } + } + + void _onUnreadCountUpdated(int count) { + unreadCount = count; + setState(ViewState.DataFetched); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/service_locator.dart b/009-realtime-feedback-app/002-final/lib/service_locator.dart index dc5f83fd..cde24908 100644 --- a/009-realtime-feedback-app/002-final/lib/service_locator.dart +++ b/009-realtime-feedback-app/002-final/lib/service_locator.dart @@ -1,15 +1,16 @@ -import 'package:get_it/get_it.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; -import 'package:skeleton_watcher/services/firebase_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - // Register services - locator.registerLazySingleton(() => FirebaseService()); - - // Register ScopedModels - locator.registerFactory(() => HomeViewModel()); - locator.registerSingleton(FeedbackViewModel()); -} +import 'package:get_it/get_it.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; +import 'package:skeleton_watcher/services/firebase_service.dart'; + +GetIt locator = new GetIt(); + +void setupLocator() { + // Register services + locator.registerLazySingleton(() => FirebaseService()); + + // Register ScopedModels + locator.registerFactory(() => HomeViewModel()); + locator.registerSingleton(FeedbackViewModel()); +} + diff --git a/009-realtime-feedback-app/002-final/lib/services/firebase_service.dart b/009-realtime-feedback-app/002-final/lib/services/firebase_service.dart index 7fd98122..379dd94d 100644 --- a/009-realtime-feedback-app/002-final/lib/services/firebase_service.dart +++ b/009-realtime-feedback-app/002-final/lib/services/firebase_service.dart @@ -1,76 +1,76 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:meta/meta.dart'; -import 'package:skeleton_watcher/models/stats.dart'; -import 'package:skeleton_watcher/models/user_feedback.dart'; - -class FirebaseService { - final StreamController _statsController = StreamController(); - - final StreamController> _feedbackController = - StreamController>(); - - final StreamController _unreadController = StreamController(); - - FirebaseService() { - Firestore.instance - .collection('informations') - .document('project_stats') - .snapshots() - .listen(_statsUpdated); - - Firestore.instance - .collection('feedback') - .where('open', isEqualTo: true) - .snapshots() - .listen(_feedbackAdded); - } - - Stream get appStats => _statsController.stream; - - Stream> get feedback => _feedbackController.stream; - - Stream get unreadCount => _unreadController.stream; - - void markFeedbackAsRead({@required String feedbackId}) { - Firestore.instance - .collection('feedback') - .document(feedbackId) - .updateData({ - 'read': true - }); - } - - void _statsUpdated(DocumentSnapshot snapshot) { - _statsController.add(Stats.fromSnapshot(snapshot)); - } - - void _feedbackAdded(QuerySnapshot snapshot) { - var feedback = _getFeedbackFromSnapshot(snapshot); - _feedbackController.add(feedback); - _emitUnreadCount(feedback); - } - - List _getFeedbackFromSnapshot(QuerySnapshot snapshot) { - var feedbackItems = List(); - var documents = snapshot.documents; - - var hasDocuments = documents.length > 0; - - if(hasDocuments) { - for (var document in documents) { - var documentData = document.data; - documentData['id'] = document.documentID; - feedbackItems.add(UserFeedback.fromData(documentData)); - } - } - - return feedbackItems; - } - - void _emitUnreadCount(List userFeedback) { - var unreadCount = userFeedback.where((item) => !item.read).length; - _unreadController.add(unreadCount); - } -} +import 'dart:async'; + +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:meta/meta.dart'; +import 'package:skeleton_watcher/models/stats.dart'; +import 'package:skeleton_watcher/models/user_feedback.dart'; + +class FirebaseService { + final StreamController _statsController = StreamController(); + + final StreamController> _feedbackController = + StreamController>(); + + final StreamController _unreadController = StreamController(); + + FirebaseService() { + Firestore.instance + .collection('informations') + .document('project_stats') + .snapshots() + .listen(_statsUpdated); + + Firestore.instance + .collection('feedback') + .where('open', isEqualTo: true) + .snapshots() + .listen(_feedbackAdded); + } + + Stream get appStats => _statsController.stream; + + Stream> get feedback => _feedbackController.stream; + + Stream get unreadCount => _unreadController.stream; + + void markFeedbackAsRead({@required String feedbackId}) { + Firestore.instance + .collection('feedback') + .document(feedbackId) + .updateData({ + 'read': true + }); + } + + void _statsUpdated(DocumentSnapshot snapshot) { + _statsController.add(Stats.fromSnapshot(snapshot)); + } + + void _feedbackAdded(QuerySnapshot snapshot) { + var feedback = _getFeedbackFromSnapshot(snapshot); + _feedbackController.add(feedback); + _emitUnreadCount(feedback); + } + + List _getFeedbackFromSnapshot(QuerySnapshot snapshot) { + var feedbackItems = List(); + var documents = snapshot.documents; + + var hasDocuments = documents.length > 0; + + if(hasDocuments) { + for (var document in documents) { + var documentData = document.data; + documentData['id'] = document.documentID; + feedbackItems.add(UserFeedback.fromData(documentData)); + } + } + + return feedbackItems; + } + + void _emitUnreadCount(List userFeedback) { + var unreadCount = userFeedback.where((item) => !item.read).length; + _unreadController.add(unreadCount); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/shared/app_colors.dart b/009-realtime-feedback-app/002-final/lib/ui/shared/app_colors.dart index e5ca3a2c..d976c11e 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/shared/app_colors.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/shared/app_colors.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); +import 'package:flutter/material.dart'; + +const Color lightGrey = Color.fromARGB(255,61,63,69); +const Color darkGrey = Color.fromARGB(255,18,18,19); +const Color primaryColor = Color.fromARGB(255, 9, 202, 172); +const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/009-realtime-feedback-app/002-final/lib/ui/shared/font_styles.dart b/009-realtime-feedback-app/002-final/lib/ui/shared/font_styles.dart index d224f955..bed44618 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/shared/font_styles.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/shared/font_styles.dart @@ -1,5 +1,5 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +const TextStyle viewTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800); const TextStyle viewErrorTitle = TextStyle(fontSize: 20.0, fontWeight: FontWeight.w800, color: lightGrey); \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/lib/ui/shared/ui_helpers.dart b/009-realtime-feedback-app/002-final/lib/ui/shared/ui_helpers.dart index 8665bf7c..390780a6 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/shared/ui_helpers.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/shared/ui_helpers.dart @@ -1,114 +1,114 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 20.0; - static const double _VerticalSpaceMedium = 40.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 20.0; - static const double _HorizontalSpaceMedium = 40.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } - - /// Provides an input field with a title that stretches the full width of the screen - static Widget inputField({ - String title, - String placeholder, - @required TextEditingController controller, - String validationMessage, - bool isPassword = false, - double spaceBetweenTitle = 15.0, - double padding = 10.0}) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(title, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), - validationMessage != null ? Text( - validationMessage, - style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), - Container( - alignment: Alignment(0.0, 0.0), - padding: EdgeInsets.only(left: padding), - margin: EdgeInsets.only(top: spaceBetweenTitle), - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: lightGrey - ), - child: TextField( - controller: controller, - obscureText: isPassword, - style: TextStyle(fontSize: 12.0), - decoration: InputDecoration.collapsed( - hintText: placeholder, - hintStyle: - TextStyle(color: Colors.grey[600], fontSize: 12.0)), - ), - ) - ]); - } - - static Widget fullScreenButton({ - String title, - Function onTap - }) { - return GestureDetector( - onTap: onTap , - child: Container( - width: double.infinity, - height: 40.0, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), - color: Color.fromARGB(255, 9, 202, 172)), - child: Center( - child: - Text(title, style: TextStyle(fontWeight: FontWeight.w800))), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +/// Contains useful functions to reduce boilerplate code +class UIHelper { + // Vertical spacing constants. Adjust to your liking. + static const double _VerticalSpaceSmall = 20.0; + static const double _VerticalSpaceMedium = 40.0; + static const double _VerticalSpaceLarge = 60.0; + + // Vertical spacing constants. Adjust to your liking. + static const double _HorizontalSpaceSmall = 20.0; + static const double _HorizontalSpaceMedium = 40.0; + static const double HorizontalSpaceLarge = 60.0; + + /// Returns a vertical space with height set to [_VerticalSpaceSmall] + static Widget verticalSpaceSmall() { + return verticalSpace(_VerticalSpaceSmall); + } + + /// Returns a vertical space with height set to [_VerticalSpaceMedium] + static Widget verticalSpaceMedium() { + return verticalSpace(_VerticalSpaceMedium); + } + + /// Returns a vertical space with height set to [_VerticalSpaceLarge] + static Widget verticalSpaceLarge() { + return verticalSpace(_VerticalSpaceLarge); + } + + /// Returns a vertical space equal to the [height] supplied + static Widget verticalSpace(double height) { + return Container(height: height); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceSmall] + static Widget horizontalSpaceSmall() { + return horizontalSpace(_HorizontalSpaceSmall); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceMedium] + static Widget horizontalSpaceMedium() { + return horizontalSpace(_HorizontalSpaceMedium); + } + + /// Returns a vertical space with height set to [HorizontalSpaceLarge] + static Widget horizontalSpaceLarge() { + return horizontalSpace(HorizontalSpaceLarge); + } + + /// Returns a vertical space equal to the [width] supplied + static Widget horizontalSpace(double width) { + return Container(width: width); + } + + /// Provides an input field with a title that stretches the full width of the screen + static Widget inputField({ + String title, + String placeholder, + @required TextEditingController controller, + String validationMessage, + bool isPassword = false, + double spaceBetweenTitle = 15.0, + double padding = 10.0}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(title, + style: TextStyle(fontWeight: FontWeight.w700, fontSize: 12.0)), + validationMessage != null ? Text( + validationMessage, + style: TextStyle(color: Colors.red[400], fontSize: 12.0)) : Container(), + Container( + alignment: Alignment(0.0, 0.0), + padding: EdgeInsets.only(left: padding), + margin: EdgeInsets.only(top: spaceBetweenTitle), + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: lightGrey + ), + child: TextField( + controller: controller, + obscureText: isPassword, + style: TextStyle(fontSize: 12.0), + decoration: InputDecoration.collapsed( + hintText: placeholder, + hintStyle: + TextStyle(color: Colors.grey[600], fontSize: 12.0)), + ), + ) + ]); + } + + static Widget fullScreenButton({ + String title, + Function onTap + }) { + return GestureDetector( + onTap: onTap , + child: Container( + width: double.infinity, + height: 40.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), + color: Color.fromARGB(255, 9, 202, 172)), + child: Center( + child: + Text(title, style: TextStyle(fontWeight: FontWeight.w800))), + ), + ); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/shared/ui_reducers.dart b/009-realtime-feedback-app/002-final/lib/ui/shared/ui_reducers.dart index 54c9c712..0e8b0fb4 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/shared/ui_reducers.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/shared/ui_reducers.dart @@ -1,7 +1,7 @@ -import 'package:flutter/widgets.dart'; - -double screenHeight(BuildContext context, - {int dividedBy = 1, double decreasedBy = 0.0}) { - assert(dividedBy != 0, "Don't divide by 0"); - return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; -} +import 'package:flutter/widgets.dart'; + +double screenHeight(BuildContext context, + {int dividedBy = 1, double decreasedBy = 0.0}) { + assert(dividedBy != 0, "Don't divide by 0"); + return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/views/base_view.dart b/009-realtime-feedback-app/002-final/lib/ui/views/base_view.dart index 042f5f47..dcda33b3 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/views/base_view.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/views/base_view.dart @@ -1,40 +1,40 @@ -import 'package:flutter/material.dart'; -import 'package:scoped_model/scoped_model.dart'; -import 'package:skeleton_watcher/service_locator.dart'; - -class BaseView extends StatefulWidget { - - final ScopedModelDescendantBuilder _builder; - - /// Function will be called as soon as the widget is initialised. - /// - /// Callback will reive the model that was created and supplied to the ScopedModel - final Function(T) onModelReady; - - BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) - : _builder = builder; - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T _model = locator(); - - @override - void initState() { - if(widget.onModelReady != null) { - widget.onModelReady(_model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ScopedModel( - model: _model, - child: ScopedModelDescendant( - child: Container(color: Colors.red), - builder: widget._builder)); - } -} +import 'package:flutter/material.dart'; +import 'package:scoped_model/scoped_model.dart'; +import 'package:skeleton_watcher/service_locator.dart'; + +class BaseView extends StatefulWidget { + + final ScopedModelDescendantBuilder _builder; + + /// Function will be called as soon as the widget is initialised. + /// + /// Callback will reive the model that was created and supplied to the ScopedModel + final Function(T) onModelReady; + + BaseView({ScopedModelDescendantBuilder builder, this.onModelReady}) + : _builder = builder; + + @override + _BaseViewState createState() => _BaseViewState(); +} + +class _BaseViewState extends State> { + T _model = locator(); + + @override + void initState() { + if(widget.onModelReady != null) { + widget.onModelReady(_model); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ScopedModel( + model: _model, + child: ScopedModelDescendant( + child: Container(color: Colors.red), + builder: widget._builder)); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/views/feedback_view.dart b/009-realtime-feedback-app/002-final/lib/ui/views/feedback_view.dart index 56cc28af..2af48a02 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/views/feedback_view.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/views/feedback_view.dart @@ -1,100 +1,102 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; -import 'package:skeleton_watcher/ui/shared/font_styles.dart'; -import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; -import 'package:skeleton_watcher/ui/widgets/feedback_item.dart'; -import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; - -class FeedbackView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, childe, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: Column( - children: [ - WatcherToolbar(title: 'FEEDBACK', showBackButton: true), - Container( - height: screenHeight(context, decreasedBy: toolbarHeight), - child: _getBodyUi(context, model)), - ], - ))); - } - - Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { - switch (model.state) { - case ViewState.Busy: - return _getLoadingUi(context); - case ViewState.NoDataAvailable: - return _noDataUi(context, model); - case ViewState.Error: - return _errorUi(context, model); - case ViewState.DataFetched: - default: - return _getListUi(model); - } - } - - Widget _getListUi(FeedbackViewModel model) { - return ListView.builder( - itemCount: model.userFeedback.length, - itemBuilder: (context, itemIndex) { - var feedbackItem = model.userFeedback[itemIndex]; - return FeedbackItem( - feedbackItem: feedbackItem, - onOpened: (feedbackId) { - model.markFeedbackAsRead(feedbackId: feedbackId); - }); - }); - } - - Widget _getLoadingUi(BuildContext context) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator( - valueColor: - AlwaysStoppedAnimation(Theme.of(context).primaryColor)), - Text('Fetching data ...') - ], - )); - } - - Widget _noDataUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage(context, "No data available yet", model); - } - - Widget _errorUi(BuildContext context, FeedbackViewModel model) { - return _getCenteredViewMessage( - context, "Error retrieving your data. Tap to try again", model, - error: true); - } - - Widget _getCenteredViewMessage( - BuildContext context, String message, FeedbackViewModel model, - {bool error = false}) { - return Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - message, - style: viewErrorTitle, - textAlign: TextAlign.center, - ), - error - ? Icon( - // WWrap in gesture detector and call you refresh future here - Icons.refresh, - color: Colors.white, - size: 45.0, - ) - : Container() - ], - ))); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/models/list_item.dart'; +import 'package:skeleton_watcher/scoped_models/feedback_view_model.dart'; +import 'package:skeleton_watcher/ui/shared/font_styles.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; +import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; +import 'package:skeleton_watcher/ui/widgets/feedback_item.dart'; +import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; + +class FeedbackView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, childe, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: Column( + children: [ + WatcherToolbar(title: 'FEEDBACK', showBackButton: true), + Container( + height: screenHeight(context, decreasedBy: toolbarHeight), + child: _getBodyUi(context, model)), + ], + ))); + } + + Widget _getBodyUi(BuildContext context, FeedbackViewModel model) { + switch (model.state) { + case ViewState.Busy: + return _getLoadingUi(context); + case ViewState.NoDataAvailable: + return _noDataUi(context, model); + case ViewState.Error: + return _errorUi(context, model); + case ViewState.DataFetched: + default: + return _getListUi(model); + } + } + + Widget _getListUi(FeedbackViewModel model) { + return ListView.builder( + itemCount: model.userFeedback.length, + itemBuilder: (context, itemIndex) { + var feedbackItem = model.userFeedback[itemIndex]; + return FeedbackItem( + feedbackItem: feedbackItem, + onOpened: (feedbackId) { + model.markFeedbackAsRead(feedbackId: feedbackId); + }); + }); + } + + Widget _getLoadingUi(BuildContext context) { + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator( + valueColor: + AlwaysStoppedAnimation(Theme.of(context).primaryColor)), + Text('Fetching data ...') + ], + )); + } + + Widget _noDataUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage(context, "No data available yet", model); + } + + Widget _errorUi(BuildContext context, FeedbackViewModel model) { + return _getCenteredViewMessage( + context, "Error retrieving your data. Tap to try again", model, + error: true); + } + + Widget _getCenteredViewMessage( + BuildContext context, String message, FeedbackViewModel model, + {bool error = false}) { + return Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + message, + style: viewErrorTitle, + textAlign: TextAlign.center, + ), + error + ? Icon( + // WWrap in gesture detector and call you refresh future here + Icons.refresh, + color: Colors.white, + size: 45.0, + ) + : Container() + ], + ))); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/views/home_view.dart b/009-realtime-feedback-app/002-final/lib/ui/views/home_view.dart index 4bec7802..a03e7a7b 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/views/home_view.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/views/home_view.dart @@ -1,93 +1,93 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/enums/view_state.dart'; -import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; -import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; -import 'package:skeleton_watcher/ui/views/base_view.dart'; -import 'package:skeleton_watcher/ui/views/feedback_view.dart'; -import 'package:skeleton_watcher/ui/widgets/indicator_button.dart'; -import 'package:skeleton_watcher/ui/widgets/stats_counter.dart'; -import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; - -class HomeView extends StatelessWidget { - static const BoxDecoration topLineBorderDecoration = BoxDecoration( - border: Border( - top: BorderSide( - color: lightGrey, style: BorderStyle.solid, width: 5.0))); - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, child, model) => Scaffold( - backgroundColor: Theme.of(context).backgroundColor, - body: _getBody(model, context))); - } - - Widget _getBody(HomeViewModel model, BuildContext context) { - switch (model.state) { - case ViewState.Busy: - case ViewState.Idle: - return Center(child: CircularProgressIndicator()); - default: - return _getStatsUi(model, context); - } - } - - Widget _getStatsUi(HomeViewModel model, BuildContext context) { - return Column(children: [ - WatcherToolbar(title: 'SKELETON-WATCHER'), - _getHeightContainer( - context: context, - height: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), - child: StatsCounter( - size: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight) - 60, // 60 margins - count: model.appStats.errorCount, - title: 'Errors', - titleColor: Colors.red, - ), - ), - _getHeightContainer( - context: context, - height:screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - StatsCounter( - size: screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight) - 60, - count: model.appStats.userCount, - title: 'Users', - ), - StatsCounter( - size: screenHeight(context,dividedBy: 3, decreasedBy: toolbarHeight) - 60, - count: model.appStats.appCount, - title: 'Apps Created', - ) - ]) - ), - _getHeightContainer( - height:screenHeight(context, dividedBy: 6, decreasedBy: toolbarHeight), - child: IndicatorButton( - title: 'FEEDBACK', - onTap: () { - Navigator.push(context, - MaterialPageRoute(builder: (context) => FeedbackView())); - }, - indicationCount: model.unreadCount, - )) - ]); - } - - Widget _getHeightContainer( - {double height, - BuildContext context, - Widget child, - bool hasTopStroke = false}) { - return Container( - height: height, - alignment: Alignment.center, - margin: EdgeInsets.symmetric(horizontal: 20.0), - decoration: hasTopStroke? topLineBorderDecoration : null, - child: child); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/enums/view_state.dart'; +import 'package:skeleton_watcher/scoped_models/home_view_model.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; +import 'package:skeleton_watcher/ui/shared/ui_reducers.dart'; +import 'package:skeleton_watcher/ui/views/base_view.dart'; +import 'package:skeleton_watcher/ui/views/feedback_view.dart'; +import 'package:skeleton_watcher/ui/widgets/indicator_button.dart'; +import 'package:skeleton_watcher/ui/widgets/stats_counter.dart'; +import 'package:skeleton_watcher/ui/widgets/watcher_toolbar.dart'; + +class HomeView extends StatelessWidget { + static const BoxDecoration topLineBorderDecoration = BoxDecoration( + border: Border( + top: BorderSide( + color: lightGrey, style: BorderStyle.solid, width: 5.0))); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, child, model) => Scaffold( + backgroundColor: Theme.of(context).backgroundColor, + body: _getBody(model, context))); + } + + Widget _getBody(HomeViewModel model, BuildContext context) { + switch (model.state) { + case ViewState.Busy: + case ViewState.Idle: + return Center(child: CircularProgressIndicator()); + default: + return _getStatsUi(model, context); + } + } + + Widget _getStatsUi(HomeViewModel model, BuildContext context) { + return Column(children: [ + WatcherToolbar(title: 'SKELETON-WATCHER'), + _getHeightContainer( + context: context, + height: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), + child: StatsCounter( + size: screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight) - 60, // 60 margins + count: model.appStats.errorCount, + title: 'Errors', + titleColor: Colors.red, + ), + ), + _getHeightContainer( + context: context, + height:screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + StatsCounter( + size: screenHeight(context, dividedBy: 3, decreasedBy: toolbarHeight) - 60, + count: model.appStats.userCount, + title: 'Users', + ), + StatsCounter( + size: screenHeight(context,dividedBy: 3, decreasedBy: toolbarHeight) - 60, + count: model.appStats.appCount, + title: 'Apps Created', + ) + ]) + ), + _getHeightContainer( + height:screenHeight(context, dividedBy: 6, decreasedBy: toolbarHeight), + child: IndicatorButton( + title: 'FEEDBACK', + onTap: () { + Navigator.push(context, + MaterialPageRoute(builder: (context) => FeedbackView())); + }, + indicationCount: model.unreadCount, + )) + ]); + } + + Widget _getHeightContainer( + {double height, + BuildContext context, + Widget child, + bool hasTopStroke = false}) { + return Container( + height: height, + alignment: Alignment.center, + margin: EdgeInsets.symmetric(horizontal: 20.0), + decoration: hasTopStroke? topLineBorderDecoration : null, + child: child); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/widgets/busy_overlay.dart b/009-realtime-feedback-app/002-final/lib/ui/widgets/busy_overlay.dart index 24f0f4b6..f2617207 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/widgets/busy_overlay.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/widgets/busy_overlay.dart @@ -1,45 +1,45 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} +import 'package:flutter/material.dart'; + +/// A modal overlay that will show over your child widget (fullscreen) when the show value is true +/// +/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when +/// your model state is Busy +class BusyOverlay extends StatelessWidget { + final Widget child; + final String title; + final bool show; + + const BusyOverlay({this.child, + this.title = 'Please wait...', + this.show = false}); + + @override + Widget build(BuildContext context) { + var screenSize = MediaQuery.of(context).size; + return Material( + child: Stack(children: [ + child, + IgnorePointer( + child: Opacity( + opacity: show ? 1.0 : 0.0, + child: Container( + width: screenSize.width, + height: screenSize.height, + alignment: Alignment.center, + color: Color.fromARGB(100, 0, 0, 0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + CircularProgressIndicator(), + Text(title, + style: TextStyle( + fontSize: 16.0, + fontWeight: FontWeight.bold, + color: Colors.white)), + ], + ), + )), + ), + ])); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_item.dart b/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_item.dart index a3dfd472..734d8b3f 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_item.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_item.dart @@ -1,112 +1,112 @@ -import 'dart:async'; - -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/models/user_feedback.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -import 'feedback_label.dart'; - -class FeedbackItem extends StatefulWidget { - final Function(String) onOpened; - - const FeedbackItem({ - @required this.feedbackItem, - @required this.onOpened, - }); - - final UserFeedback feedbackItem; - - @override - _FeedbackItemState createState() => _FeedbackItemState(); -} - -class _FeedbackItemState extends State { - double _height = 70.0; - bool _showDetails = false; - - static const double descriptionPadding = 15.0; - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - duration: Duration(milliseconds: 200), - curve: Curves.easeIn, - width: double.infinity, - height: _height, - margin: EdgeInsets.symmetric(vertical: 5, horizontal: 10), - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: darkGrey), - child: Row( - children: [_detailsSection, _notificationSection], - ), - ); - } - - Widget get _detailsSection => Expanded( - child: GestureDetector( - onTap: () { - setState(() { - if (!_showDetails) { - _height = 190; - } else { - _height = 70.0; - } - }); - - Timer.periodic(Duration(milliseconds: 150), (timer) { - timer.cancel(); - - if(widget.onOpened != null) { - widget.onOpened(widget.feedbackItem.id); - } - - setState(() { - _showDetails = !_showDetails; - }); - }); - }, - child: Container( - color: darkGrey, - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(widget.feedbackItem.title, - maxLines: 1, style: TextStyle(fontWeight: FontWeight.bold)), - _showDetails - ? Padding( - padding: const EdgeInsets.symmetric( - vertical: descriptionPadding), - child: Text(widget.feedbackItem.details), - ) - : Container(), - Expanded( - child: Align( - child: FeedbackLabel(type: widget.feedbackItem.type), - alignment: Alignment.bottomLeft)) - ], - ), - ), - )); - - Widget get _notificationSection => Container( - width: 50.0, - child: Column(children: [ - !widget.feedbackItem.read - ? Container( - width: 20, - height: 20, - decoration: - ShapeDecoration(shape: CircleBorder(), color: primaryColor)) - : Container(), - Expanded( - child: Align( - alignment: Alignment.bottomCenter, - child: Text('Today', - style: TextStyle( - color: lightGrey, - fontWeight: FontWeight.bold, - fontSize: 9.0)))) - ])); -} +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/models/user_feedback.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +import 'feedback_label.dart'; + +class FeedbackItem extends StatefulWidget { + final Function(String) onOpened; + + const FeedbackItem({ + @required this.feedbackItem, + @required this.onOpened, + }); + + final UserFeedback feedbackItem; + + @override + _FeedbackItemState createState() => _FeedbackItemState(); +} + +class _FeedbackItemState extends State { + double _height = 70.0; + bool _showDetails = false; + + static const double descriptionPadding = 15.0; + + @override + Widget build(BuildContext context) { + return AnimatedContainer( + duration: Duration(milliseconds: 200), + curve: Curves.easeIn, + width: double.infinity, + height: _height, + margin: EdgeInsets.symmetric(vertical: 5, horizontal: 10), + padding: EdgeInsets.all(10.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: darkGrey), + child: Row( + children: [_detailsSection, _notificationSection], + ), + ); + } + + Widget get _detailsSection => Expanded( + child: GestureDetector( + onTap: () { + setState(() { + if (!_showDetails) { + _height = 190; + } else { + _height = 70.0; + } + }); + + Timer.periodic(Duration(milliseconds: 150), (timer) { + timer.cancel(); + + if(widget.onOpened != null) { + widget.onOpened(widget.feedbackItem.id); + } + + setState(() { + _showDetails = !_showDetails; + }); + }); + }, + child: Container( + color: darkGrey, + child: Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(widget.feedbackItem.title, + maxLines: 1, style: TextStyle(fontWeight: FontWeight.bold)), + _showDetails + ? Padding( + padding: const EdgeInsets.symmetric( + vertical: descriptionPadding), + child: Text(widget.feedbackItem.details), + ) + : Container(), + Expanded( + child: Align( + child: FeedbackLabel(type: widget.feedbackItem.type), + alignment: Alignment.bottomLeft)) + ], + ), + ), + )); + + Widget get _notificationSection => Container( + width: 50.0, + child: Column(children: [ + !widget.feedbackItem.read + ? Container( + width: 20, + height: 20, + decoration: + ShapeDecoration(shape: CircleBorder(), color: primaryColor)) + : Container(), + Expanded( + child: Align( + alignment: Alignment.bottomCenter, + child: Text('Today', + style: TextStyle( + color: lightGrey, + fontWeight: FontWeight.bold, + fontSize: 9.0)))) + ])); +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_label.dart b/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_label.dart index 2cf38074..216b54e2 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_label.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/widgets/feedback_label.dart @@ -1,49 +1,49 @@ -import 'package:flutter/material.dart'; - -enum LabelType { Bug, Request, General } - -class FeedbackLabel extends StatelessWidget { - final int type; - - FeedbackLabel({@required this.type}); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 4, vertical: 2), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(3.0), - color: _getLabelColor(_getTypeForType())), - child: Text(_getLabelName())); - } - - String _getLabelName() { - return _getTypeForType().toString().split('.').last; - } - - LabelType _getTypeForType() { - switch (type) { - case 0: - return LabelType.Bug; - case 1: - return LabelType.Request; - case 2: - return LabelType.General; - } - - return LabelType.Bug; - } - - Color _getLabelColor(LabelType label) { - switch (label) { - case LabelType.Bug: - return Color.fromARGB(255, 202, 9, 9); - case LabelType.Request: - return Color.fromARGB(255, 9, 71, 202); - case LabelType.General: - return Color.fromARGB(255, 202, 134, 9); - } - - return null; - } +import 'package:flutter/material.dart'; + +enum LabelType { Bug, Request, General } + +class FeedbackLabel extends StatelessWidget { + final int type; + + FeedbackLabel({@required this.type}); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 4, vertical: 2), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(3.0), + color: _getLabelColor(_getTypeForType())), + child: Text(_getLabelName())); + } + + String _getLabelName() { + return _getTypeForType().toString().split('.').last; + } + + LabelType _getTypeForType() { + switch (type) { + case 0: + return LabelType.Bug; + case 1: + return LabelType.Request; + case 2: + return LabelType.General; + } + + return LabelType.Bug; + } + + Color _getLabelColor(LabelType label) { + switch (label) { + case LabelType.Bug: + return Color.fromARGB(255, 202, 9, 9); + case LabelType.Request: + return Color.fromARGB(255, 9, 71, 202); + case LabelType.General: + return Color.fromARGB(255, 202, 134, 9); + } + + return null; + } } \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/lib/ui/widgets/indicator_button.dart b/009-realtime-feedback-app/002-final/lib/ui/widgets/indicator_button.dart index 6cb88f6b..d617fe2a 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/widgets/indicator_button.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/widgets/indicator_button.dart @@ -1,47 +1,47 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -class IndicatorButton extends StatelessWidget { - final double height; - final String title; - final Function onTap; - final int indicationCount; - - const IndicatorButton({this.height = 50.0, this.title, this.onTap, this.indicationCount}); - - bool get hasIndication => indicationCount != null && indicationCount > 0; - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - height: height, - child: Stack(children: [ - Container( - height: height, - width: double.infinity, - alignment: Alignment.center, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: primaryColor), - child: Text( - title, - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), - )), - hasIndication ? Positioned( - top: 10, - right: 20.0, - child: Container( - width: 30, - height: 30, - alignment: Alignment.center, - decoration: - ShapeDecoration(shape: CircleBorder(), color: darkGrey), - child: Text(indicationCount.toString(), - style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400)), - ), - ) : Container() - ]), - )); - } +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +class IndicatorButton extends StatelessWidget { + final double height; + final String title; + final Function onTap; + final int indicationCount; + + const IndicatorButton({this.height = 50.0, this.title, this.onTap, this.indicationCount}); + + bool get hasIndication => indicationCount != null && indicationCount > 0; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + height: height, + child: Stack(children: [ + Container( + height: height, + width: double.infinity, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: primaryColor), + child: Text( + title, + style: TextStyle(fontSize: 16, fontWeight: FontWeight.w700), + )), + hasIndication ? Positioned( + top: 10, + right: 20.0, + child: Container( + width: 30, + height: 30, + alignment: Alignment.center, + decoration: + ShapeDecoration(shape: CircleBorder(), color: darkGrey), + child: Text(indicationCount.toString(), + style: TextStyle(fontSize: 14, fontWeight: FontWeight.w400)), + ), + ) : Container() + ]), + )); + } } \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/lib/ui/widgets/stats_counter.dart b/009-realtime-feedback-app/002-final/lib/ui/widgets/stats_counter.dart index 5d4c38e3..33532d5b 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/widgets/stats_counter.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/widgets/stats_counter.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:skeleton_watcher/ui/shared/app_colors.dart'; - -class StatsCounter extends StatelessWidget { - final double size; - final int count; - final String title; - final Color titleColor; - - StatsCounter( - {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); - - @override - Widget build(BuildContext context) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: darkGrey), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text(count.toString(), - textAlign: TextAlign.center, - style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), - Text(title, - textAlign: TextAlign.center, - style: TextStyle( - color: titleColor, - fontSize: size * 0.1, fontWeight: FontWeight.w400)) - ]), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:skeleton_watcher/ui/shared/app_colors.dart'; + +class StatsCounter extends StatelessWidget { + final double size; + final int count; + final String title; + final Color titleColor; + + StatsCounter( + {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); + + @override + Widget build(BuildContext context) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: darkGrey), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(count.toString(), + textAlign: TextAlign.center, + style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), + Text(title, + textAlign: TextAlign.center, + style: TextStyle( + color: titleColor, + fontSize: size * 0.1, fontWeight: FontWeight.w400)) + ]), + ); + } +} diff --git a/009-realtime-feedback-app/002-final/lib/ui/widgets/watcher_toolbar.dart b/009-realtime-feedback-app/002-final/lib/ui/widgets/watcher_toolbar.dart index afaf138d..8161765e 100644 --- a/009-realtime-feedback-app/002-final/lib/ui/widgets/watcher_toolbar.dart +++ b/009-realtime-feedback-app/002-final/lib/ui/widgets/watcher_toolbar.dart @@ -1,38 +1,38 @@ -import 'package:flutter/material.dart'; - -const double toolbarHeight = 80.0; - -class WatcherToolbar extends StatelessWidget { - final String title; - final bool showBackButton; - const WatcherToolbar({@required this.title, this.showBackButton = false}); - - @override - Widget build(BuildContext context) { - return Container( - height: toolbarHeight, - margin: EdgeInsets.symmetric(horizontal: 20.0), - child: Row( - children: [ - showBackButton - ? GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.centerLeft, - width: 50, - child: Icon(Icons.chevron_left, - size: 30, color: Colors.white)), - ) - : Container(), - Expanded( - child: Text(title, - textAlign: TextAlign.right, - style: TextStyle(fontWeight: FontWeight.w800)), - ), - ], - ), - ); - } +import 'package:flutter/material.dart'; + +const double toolbarHeight = 80.0; + +class WatcherToolbar extends StatelessWidget { + final String title; + final bool showBackButton; + const WatcherToolbar({@required this.title, this.showBackButton = false}); + + @override + Widget build(BuildContext context) { + return Container( + height: toolbarHeight, + margin: EdgeInsets.symmetric(horizontal: 20.0), + child: Row( + children: [ + showBackButton + ? GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Container( + alignment: Alignment.centerLeft, + width: 50, + child: Icon(Icons.chevron_left, + size: 30, color: Colors.white)), + ) + : Container(), + Expanded( + child: Text(title, + textAlign: TextAlign.right, + style: TextStyle(fontWeight: FontWeight.w800)), + ), + ], + ), + ); + } } \ No newline at end of file diff --git a/009-realtime-feedback-app/002-final/pubspec.lock b/009-realtime-feedback-app/002-final/pubspec.lock index 6afbe482..10d0e190 100644 --- a/009-realtime-feedback-app/002-final/pubspec.lock +++ b/009-realtime-feedback-app/002-final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,28 +7,21 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.2.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" cloud_firestore: dependency: "direct main" description: @@ -42,21 +35,14 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" firebase_core: dependency: transitive description: @@ -80,28 +66,42 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "1.0.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" scoped_model: dependency: "direct main" description: @@ -120,7 +120,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -141,7 +141,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -155,7 +155,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.5" typed_data: dependency: transitive description: @@ -171,5 +171,5 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.2.0 <3.0.0" flutter: ">=1.2.0 <2.0.0" diff --git a/009-realtime-feedback-app/002-final/pubspec.yaml b/009-realtime-feedback-app/002-final/pubspec.yaml index 4ab6d96d..b9aafeca 100644 --- a/009-realtime-feedback-app/002-final/pubspec.yaml +++ b/009-realtime-feedback-app/002-final/pubspec.yaml @@ -1,76 +1,78 @@ -name: skeleton_watcher -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # scoped model packages - scoped_model: ^1.0.1 - # get it - get_it: ^4.0.2 - # firebase firestore - cloud_firestore: - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages +name: skeleton_watcher +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + # scoped model packages + scoped_model: ^1.0.1 + # get it + get_it: ^1.0.3 + # firebase firestore + cloud_firestore: + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: Open Sans + fonts: + - asset: assets/fonts/OpenSans-Bold.ttf + weight: 700 + - asset: assets/fonts/OpenSans-ExtraBold.ttf + weight: 800 + - asset: assets/fonts/OpenSans-Light.ttf + weight: 300 + - asset: assets/fonts/OpenSans-Regular.ttf + weight: 400 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/009-realtime-feedback-app/002-final/test/widget_test.dart b/009-realtime-feedback-app/002-final/test/widget_test.dart index ee9c85de..688c5230 100644 --- a/009-realtime-feedback-app/002-final/test/widget_test.dart +++ b/009-realtime-feedback-app/002-final/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:skeleton_watcher/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:skeleton_watcher/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/010-provider-architecture/001-start/.gitignore b/010-provider-architecture/001-start/.gitignore index 5be59a14..07488ba6 100644 --- a/010-provider-architecture/001-start/.gitignore +++ b/010-provider-architecture/001-start/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/010-provider-architecture/001-start/.metadata b/010-provider-architecture/001-start/.metadata index b9fdc6b5..101035a8 100644 --- a/010-provider-architecture/001-start/.metadata +++ b/010-provider-architecture/001-start/.metadata @@ -1,10 +1,10 @@ -# 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: fbe11671a4b78a707d9856588d956c0d3c39a6d5 - channel: master - -project_type: app +# 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: fbe11671a4b78a707d9856588d956c0d3c39a6d5 + channel: master + +project_type: app diff --git a/010-provider-architecture/001-start/README.md b/010-provider-architecture/001-start/README.md index 7f4b5dc9..10f3ffc7 100644 --- a/010-provider-architecture/001-start/README.md +++ b/010-provider-architecture/001-start/README.md @@ -1,3 +1,3 @@ -# Provider + Get_it Architecture - +# Provider + Get_it Architecture + This is the starting code for [this tutorial](https://www.filledstacks.com/post/flutter-architecture-my-provider-implementation-guide) where we setup a Flutter app architecture using the Provider package. \ No newline at end of file diff --git a/010-provider-architecture/001-start/android/app/build.gradle b/010-provider-architecture/001-start/android/app/build.gradle new file mode 100644 index 00000000..68680055 --- /dev/null +++ b/010-provider-architecture/001-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.provider_architecutre" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/010-provider-architecture/001-start/android/app/src/debug/AndroidManifest.xml b/010-provider-architecture/001-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..83579b8e --- /dev/null +++ b/010-provider-architecture/001-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/010-provider-architecture/001-start/android/app/src/main/AndroidManifest.xml b/010-provider-architecture/001-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..36518eb8 --- /dev/null +++ b/010-provider-architecture/001-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/010-provider-architecture/001-start/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java b/010-provider-architecture/001-start/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java new file mode 100644 index 00000000..ef4254d4 --- /dev/null +++ b/010-provider-architecture/001-start/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.provider_architecutre; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/010-provider-architecture/001-start/android/app/src/main/res/drawable/launch_background.xml b/010-provider-architecture/001-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/010-provider-architecture/001-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/010-provider-architecture/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/010-provider-architecture/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/010-provider-architecture/001-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/001-start/android/app/src/main/res/values/styles.xml b/010-provider-architecture/001-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/010-provider-architecture/001-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/010-provider-architecture/001-start/android/app/src/profile/AndroidManifest.xml b/010-provider-architecture/001-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..83579b8e --- /dev/null +++ b/010-provider-architecture/001-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/010-provider-architecture/001-start/android/build.gradle b/010-provider-architecture/001-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/010-provider-architecture/001-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/010-provider-architecture/001-start/android/gradle.properties b/010-provider-architecture/001-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/010-provider-architecture/001-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/010-provider-architecture/001-start/android/gradle/wrapper/gradle-wrapper.properties b/010-provider-architecture/001-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/010-provider-architecture/001-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/010-provider-architecture/001-start/android/settings.gradle b/010-provider-architecture/001-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/010-provider-architecture/001-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/010-provider-architecture/001-start/ios/Flutter/AppFrameworkInfo.plist b/010-provider-architecture/001-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/010-provider-architecture/001-start/ios/Flutter/Debug.xcconfig b/010-provider-architecture/001-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/010-provider-architecture/001-start/ios/Flutter/Release.xcconfig b/010-provider-architecture/001-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/010-provider-architecture/001-start/ios/Runner.xcodeproj/project.pbxproj b/010-provider-architecture/001-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..e836bcfe --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/010-provider-architecture/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/010-provider-architecture/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/010-provider-architecture/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/010-provider-architecture/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/010-provider-architecture/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/010-provider-architecture/001-start/ios/Runner/AppDelegate.h b/010-provider-architecture/001-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/010-provider-architecture/001-start/ios/Runner/AppDelegate.m b/010-provider-architecture/001-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/010-provider-architecture/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/010-provider-architecture/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/001-start/ios/Runner/Base.lproj/Main.storyboard b/010-provider-architecture/001-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/001-start/ios/Runner/Info.plist b/010-provider-architecture/001-start/ios/Runner/Info.plist new file mode 100644 index 00000000..55ae3953 --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + provider_architecutre + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/010-provider-architecture/001-start/ios/Runner/main.m b/010-provider-architecture/001-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/010-provider-architecture/001-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/010-provider-architecture/001-start/lib/core/models/comment.dart b/010-provider-architecture/001-start/lib/core/models/comment.dart index 6a2ebec8..2984f6f4 100644 --- a/010-provider-architecture/001-start/lib/core/models/comment.dart +++ b/010-provider-architecture/001-start/lib/core/models/comment.dart @@ -1,27 +1,27 @@ -class Comment { - int postId; - int id; - String name; - String email; - String body; - - Comment({this.postId, this.id, this.name, this.email, this.body}); - - Comment.fromJson(Map json) { - postId = json['postId']; - id = json['id']; - name = json['name']; - email = json['email']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['postId'] = this.postId; - data['id'] = this.id; - data['name'] = this.name; - data['email'] = this.email; - data['body'] = this.body; - return data; - } +class Comment { + int postId; + int id; + String name; + String email; + String body; + + Comment({this.postId, this.id, this.name, this.email, this.body}); + + Comment.fromJson(Map json) { + postId = json['postId']; + id = json['id']; + name = json['name']; + email = json['email']; + body = json['body']; + } + + Map toJson() { + final Map data = new Map(); + data['postId'] = this.postId; + data['id'] = this.id; + data['name'] = this.name; + data['email'] = this.email; + data['body'] = this.body; + return data; + } } \ No newline at end of file diff --git a/010-provider-architecture/001-start/lib/core/models/post.dart b/010-provider-architecture/001-start/lib/core/models/post.dart index c1c6cf92..845a19c9 100644 --- a/010-provider-architecture/001-start/lib/core/models/post.dart +++ b/010-provider-architecture/001-start/lib/core/models/post.dart @@ -1,24 +1,24 @@ -class Post { - int userId; - int id; - String title; - String body; - - Post({this.userId, this.id, this.title, this.body}); - - Post.fromJson(Map json) { - userId = json['userId']; - id = json['id']; - title = json['title']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['id'] = this.id; - data['title'] = this.title; - data['body'] = this.body; - return data; - } +class Post { + int userId; + int id; + String title; + String body; + + Post({this.userId, this.id, this.title, this.body}); + + Post.fromJson(Map json) { + userId = json['userId']; + id = json['id']; + title = json['title']; + body = json['body']; + } + + Map toJson() { + final Map data = new Map(); + data['userId'] = this.userId; + data['id'] = this.id; + data['title'] = this.title; + data['body'] = this.body; + return data; + } } \ No newline at end of file diff --git a/010-provider-architecture/001-start/lib/core/models/user.dart b/010-provider-architecture/001-start/lib/core/models/user.dart index 1071dc6c..4a620651 100644 --- a/010-provider-architecture/001-start/lib/core/models/user.dart +++ b/010-provider-architecture/001-start/lib/core/models/user.dart @@ -1,25 +1,25 @@ -class User { - int id; - String name; - String username; - User({this.id, this.name, this.username}); - - User.initial() - : id = 0, - name = '', - username = ''; - - User.fromJson(Map json) { - id = json['id']; - name = json['name']; - username = json['username']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['username'] = this.username; - return data; - } -} +class User { + int id; + String name; + String username; + User({this.id, this.name, this.username}); + + User.initial() + : id = 0, + name = '', + username = ''; + + User.fromJson(Map json) { + id = json['id']; + name = json['name']; + username = json['username']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['username'] = this.username; + return data; + } +} diff --git a/010-provider-architecture/001-start/lib/core/services/api.dart b/010-provider-architecture/001-start/lib/core/services/api.dart index 137f92b2..17b4aeb4 100644 --- a/010-provider-architecture/001-start/lib/core/services/api.dart +++ b/010-provider-architecture/001-start/lib/core/services/api.dart @@ -1,54 +1,54 @@ -import 'dart:convert'; - -import 'package:provider_architecture/core/models/comment.dart'; -import 'package:provider_architecture/core/models/post.dart'; -import 'package:provider_architecture/core/models/user.dart'; -import 'package:http/http.dart' as http; - -/// The service responsible for networking requests -class Api { - static const endpoint = 'https://jsonplaceholder.typicode.com'; - - var client = new http.Client(); - - Future getUserProfile(int userId) async { - // Get user profile for id - var response = await client.get('$endpoint/users/$userId'); - - // Convert and return - return User.fromJson(json.decode(response.body)); - } - - Future> getPostsForUser(int userId) async { - var posts = List(); - // Get user posts for id - var response = await client.get('$endpoint/posts?userId=$userId'); - - // parse into List - var parsed = json.decode(response.body) as List; - - // loop and convert each item to Post - for (var post in parsed) { - posts.add(Post.fromJson(post)); - } - - return posts; - } - - Future> getCommentsForPost(int postId) async { - var comments = List(); - - // Get comments for post - var response = await client.get('$endpoint/comments?postId=$postId'); - - // Parse into List - var parsed = json.decode(response.body) as List; - - // Loop and convert each item to a Comment - for (var comment in parsed) { - comments.add(Comment.fromJson(comment)); - } - - return comments; - } -} +import 'dart:convert'; + +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/models/user.dart'; +import 'package:http/http.dart' as http; + +/// The service responsible for networking requests +class Api { + static const endpoint = 'https://jsonplaceholder.typicode.com'; + + var client = new http.Client(); + + Future getUserProfile(int userId) async { + // Get user profile for id + var response = await client.get('$endpoint/users/$userId'); + + // Convert and return + return User.fromJson(json.decode(response.body)); + } + + Future> getPostsForUser(int userId) async { + var posts = List(); + // Get user posts for id + var response = await client.get('$endpoint/posts?userId=$userId'); + + // parse into List + var parsed = json.decode(response.body) as List; + + // loop and convert each item to Post + for (var post in parsed) { + posts.add(Post.fromJson(post)); + } + + return posts; + } + + Future> getCommentsForPost(int postId) async { + var comments = List(); + + // Get comments for post + var response = await client.get('$endpoint/comments?postId=$postId'); + + // Parse into List + var parsed = json.decode(response.body) as List; + + // Loop and convert each item to a Comment + for (var comment in parsed) { + comments.add(Comment.fromJson(comment)); + } + + return comments; + } +} diff --git a/010-provider-architecture/001-start/lib/locator.dart b/010-provider-architecture/001-start/lib/locator.dart index 04530e0a..6aade6d7 100644 --- a/010-provider-architecture/001-start/lib/locator.dart +++ b/010-provider-architecture/001-start/lib/locator.dart @@ -1,6 +1,6 @@ -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { +import 'package:get_it/get_it.dart'; + +GetIt locator = GetIt(); + +void setupLocator() { } \ No newline at end of file diff --git a/010-provider-architecture/001-start/lib/main.dart b/010-provider-architecture/001-start/lib/main.dart index ce4025ad..c7c576f7 100644 --- a/010-provider-architecture/001-start/lib/main.dart +++ b/010-provider-architecture/001-start/lib/main.dart @@ -1,19 +1,19 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/locator.dart'; -import 'package:provider_architecture/ui/views/login_view.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData(), - home: LoginView(), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/locator.dart'; +import 'package:provider_architecutre/ui/views/login_view.dart'; + +void main() { + setupLocator(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData(), + home: LoginView(), + ); + } +} diff --git a/010-provider-architecture/001-start/lib/ui/shared/app_colors.dart b/010-provider-architecture/001-start/lib/ui/shared/app_colors.dart index 43ad166d..76575901 100644 --- a/010-provider-architecture/001-start/lib/ui/shared/app_colors.dart +++ b/010-provider-architecture/001-start/lib/ui/shared/app_colors.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; - -const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); -const Color commentColor = Color.fromARGB(255, 255, 246, 196); +import 'package:flutter/material.dart'; + +const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); +const Color commentColor = Color.fromARGB(255, 255, 246, 196); diff --git a/010-provider-architecture/001-start/lib/ui/shared/text_styles.dart b/010-provider-architecture/001-start/lib/ui/shared/text_styles.dart index 86fec3eb..6847af85 100644 --- a/010-provider-architecture/001-start/lib/ui/shared/text_styles.dart +++ b/010-provider-architecture/001-start/lib/ui/shared/text_styles.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; - -const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); +import 'package:flutter/material.dart'; + +const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); \ No newline at end of file diff --git a/010-provider-architecture/001-start/lib/ui/shared/ui_helpers.dart b/010-provider-architecture/001-start/lib/ui/shared/ui_helpers.dart index 0259d89b..925640e1 100644 --- a/010-provider-architecture/001-start/lib/ui/shared/ui_helpers.dart +++ b/010-provider-architecture/001-start/lib/ui/shared/ui_helpers.dart @@ -1,54 +1,54 @@ -import 'package:flutter/material.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 10.0; - static const double _VerticalSpaceMedium = 20.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 10.0; - static const double _HorizontalSpaceMedium = 20.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } -} +import 'package:flutter/material.dart'; + +/// Contains useful functions to reduce boilerplate code +class UIHelper { + // Vertical spacing constants. Adjust to your liking. + static const double _VerticalSpaceSmall = 10.0; + static const double _VerticalSpaceMedium = 20.0; + static const double _VerticalSpaceLarge = 60.0; + + // Vertical spacing constants. Adjust to your liking. + static const double _HorizontalSpaceSmall = 10.0; + static const double _HorizontalSpaceMedium = 20.0; + static const double HorizontalSpaceLarge = 60.0; + + /// Returns a vertical space with height set to [_VerticalSpaceSmall] + static Widget verticalSpaceSmall() { + return verticalSpace(_VerticalSpaceSmall); + } + + /// Returns a vertical space with height set to [_VerticalSpaceMedium] + static Widget verticalSpaceMedium() { + return verticalSpace(_VerticalSpaceMedium); + } + + /// Returns a vertical space with height set to [_VerticalSpaceLarge] + static Widget verticalSpaceLarge() { + return verticalSpace(_VerticalSpaceLarge); + } + + /// Returns a vertical space equal to the [height] supplied + static Widget verticalSpace(double height) { + return Container(height: height); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceSmall] + static Widget horizontalSpaceSmall() { + return horizontalSpace(_HorizontalSpaceSmall); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceMedium] + static Widget horizontalSpaceMedium() { + return horizontalSpace(_HorizontalSpaceMedium); + } + + /// Returns a vertical space with height set to [HorizontalSpaceLarge] + static Widget horizontalSpaceLarge() { + return horizontalSpace(HorizontalSpaceLarge); + } + + /// Returns a vertical space equal to the [width] supplied + static Widget horizontalSpace(double width) { + return Container(width: width); + } +} diff --git a/010-provider-architecture/001-start/lib/ui/views/home_view.dart b/010-provider-architecture/001-start/lib/ui/views/home_view.dart index ace7ca40..b543ee0b 100644 --- a/010-provider-architecture/001-start/lib/ui/views/home_view.dart +++ b/010-provider-architecture/001-start/lib/ui/views/home_view.dart @@ -1,8 +1,8 @@ -import 'package:flutter/material.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold(); - } -} +import 'package:flutter/material.dart'; + +class HomeView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/010-provider-architecture/001-start/lib/ui/views/login_view.dart b/010-provider-architecture/001-start/lib/ui/views/login_view.dart index d29468c7..dca7992e 100644 --- a/010-provider-architecture/001-start/lib/ui/views/login_view.dart +++ b/010-provider-architecture/001-start/lib/ui/views/login_view.dart @@ -1,8 +1,8 @@ -import 'package:flutter/material.dart'; - -class LoginView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold(); - } -} +import 'package:flutter/material.dart'; + +class LoginView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/010-provider-architecture/001-start/lib/ui/views/post_view.dart b/010-provider-architecture/001-start/lib/ui/views/post_view.dart index 86290a06..c1a3c872 100644 --- a/010-provider-architecture/001-start/lib/ui/views/post_view.dart +++ b/010-provider-architecture/001-start/lib/ui/views/post_view.dart @@ -1,12 +1,12 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/core/models/post.dart'; - -class PostView extends StatelessWidget { - final Post post; - PostView({this.post}); - - @override - Widget build(BuildContext context) { - return Scaffold(); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/core/models/post.dart'; + +class PostView extends StatelessWidget { + final Post post; + PostView({this.post}); + + @override + Widget build(BuildContext context) { + return Scaffold(); + } +} diff --git a/010-provider-architecture/001-start/lib/ui/widgets/comments.dart b/010-provider-architecture/001-start/lib/ui/widgets/comments.dart index 86e87741..2f6d6699 100644 --- a/010-provider-architecture/001-start/lib/ui/widgets/comments.dart +++ b/010-provider-architecture/001-start/lib/ui/widgets/comments.dart @@ -1,41 +1,41 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/core/models/comment.dart'; -import 'package:provider_architecture/ui/shared/app_colors.dart'; -import 'package:provider_architecture/ui/shared/ui_helpers.dart'; - -class Comments extends StatelessWidget { - final int postId; - Comments(this.postId); - - @override - Widget build(BuildContext context) { - return Center(child: Text('I am comments ')); - } -} - -/// Renders a single comment given a comment model -class CommentItem extends StatelessWidget { - final Comment comment; - const CommentItem(this.comment); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.symmetric(vertical: 10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: commentColor), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - comment.name, - style: TextStyle(fontWeight: FontWeight.bold), - ), - UIHelper.verticalSpaceSmall(), - Text(comment.body), - ], - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; + +class Comments extends StatelessWidget { + final int postId; + Comments(this.postId); + + @override + Widget build(BuildContext context) { + return Center(child: Text('I am comments ')); + } +} + +/// Renders a single comment given a comment model +class CommentItem extends StatelessWidget { + final Comment comment; + const CommentItem(this.comment); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.symmetric(vertical: 10.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: commentColor), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + comment.name, + style: TextStyle(fontWeight: FontWeight.bold), + ), + UIHelper.verticalSpaceSmall(), + Text(comment.body), + ], + ), + ); + } +} diff --git a/010-provider-architecture/001-start/lib/ui/widgets/login_header.dart b/010-provider-architecture/001-start/lib/ui/widgets/login_header.dart index a4bf50ad..394081d1 100644 --- a/010-provider-architecture/001-start/lib/ui/widgets/login_header.dart +++ b/010-provider-architecture/001-start/lib/ui/widgets/login_header.dart @@ -1,44 +1,44 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/ui/shared/text_styles.dart'; -import 'package:provider_architecture/ui/shared/ui_helpers.dart'; - -class LoginHeader extends StatelessWidget { - final TextEditingController controller; - final String validationMessage; - - LoginHeader({@required this.controller, this.validationMessage}); - - @override - Widget build(BuildContext context) { - return Column(children: [ - Text('Login', style: headerStyle), - UIHelper.verticalSpaceMedium(), - Text('Enter a number between 1 - 10', style: subHeaderStyle), - LoginTextField(controller), - this.validationMessage != null - ? Text(validationMessage, style: TextStyle(color: Colors.red)) - : Container() - ]); - } -} - -class LoginTextField extends StatelessWidget { - final TextEditingController controller; - - LoginTextField(this.controller); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 15.0), - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), - height: 50.0, - alignment: Alignment.centerLeft, - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - child: TextField( - decoration: InputDecoration.collapsed(hintText: 'User Id'), - controller: controller), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/ui/shared/text_styles.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; + +class LoginHeader extends StatelessWidget { + final TextEditingController controller; + final String validationMessage; + + LoginHeader({@required this.controller, this.validationMessage}); + + @override + Widget build(BuildContext context) { + return Column(children: [ + Text('Login', style: headerStyle), + UIHelper.verticalSpaceMedium(), + Text('Enter a number between 1 - 10', style: subHeaderStyle), + LoginTextField(controller), + this.validationMessage != null + ? Text(validationMessage, style: TextStyle(color: Colors.red)) + : Container() + ]); + } +} + +class LoginTextField extends StatelessWidget { + final TextEditingController controller; + + LoginTextField(this.controller); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 15.0), + margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), + height: 50.0, + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10.0)), + child: TextField( + decoration: InputDecoration.collapsed(hintText: 'User Id'), + controller: controller), + ); + } +} diff --git a/010-provider-architecture/001-start/lib/ui/widgets/postlist_item.dart b/010-provider-architecture/001-start/lib/ui/widgets/postlist_item.dart index ff6e04dd..d216cf3a 100644 --- a/010-provider-architecture/001-start/lib/ui/widgets/postlist_item.dart +++ b/010-provider-architecture/001-start/lib/ui/widgets/postlist_item.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/core/models/post.dart'; - -class PostListItem extends StatelessWidget { - final Post post; - final Function onTap; - const PostListItem({this.post, this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.0), - boxShadow: [ - BoxShadow( - blurRadius: 3.0, - offset: Offset(0.0, 2.0), - color: Color.fromARGB(80, 0, 0, 0)) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(post.title, style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0),), - Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) - ], - ), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/core/models/post.dart'; + +class PostListItem extends StatelessWidget { + final Post post; + final Function onTap; + const PostListItem({this.post, this.onTap}); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), + padding: EdgeInsets.all(10.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5.0), + boxShadow: [ + BoxShadow( + blurRadius: 3.0, + offset: Offset(0.0, 2.0), + color: Color.fromARGB(80, 0, 0, 0)) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(post.title, style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0),), + Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) + ], + ), + ), + ); + } +} diff --git a/010-provider-architecture/001-start/pubspec.lock b/010-provider-architecture/001-start/pubspec.lock index 9e337945..05b5b744 100644 --- a/010-provider-architecture/001-start/pubspec.lock +++ b/010-provider-architecture/001-start/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,49 +7,35 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.9.0" + version: "2.2.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" - characters: + version: "1.0.4" + charcode: dependency: transitive description: - name: characters + name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.16.0" + version: "1.14.11" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -66,63 +52,63 @@ packages: name: get_it url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "1.0.3" http: dependency: "direct main" description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.13.5" + version: "0.12.0+2" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "4.0.2" + version: "3.1.3" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" - nested: + version: "1.1.6" + path: dependency: transitive description: - name: nested + name: path url: "https://pub.dartlang.org" source: hosted - version: "0.0.4" - path: + version: "1.6.2" + pedantic: dependency: transitive description: - name: path + name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.5.0" provider: dependency: "direct main" description: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.1.3" + version: "2.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" sky_engine: dependency: transitive description: flutter @@ -134,56 +120,55 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.9.0" + version: "1.5.5" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.10.0" + version: "1.9.3" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.0.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.0.4" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.1" + version: "1.1.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.12" + version: "0.2.5" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.1" + version: "1.1.6" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.2" + version: "2.0.8" sdks: - dart: ">=2.17.0-0 <3.0.0" - flutter: ">=1.16.0" + dart: ">2.2.2 <3.0.0" diff --git a/010-provider-architecture/001-start/pubspec.yaml b/010-provider-architecture/001-start/pubspec.yaml index 3d8f1662..2dd4fa46 100644 --- a/010-provider-architecture/001-start/pubspec.yaml +++ b/010-provider-architecture/001-start/pubspec.yaml @@ -1,69 +1,75 @@ -name: provider_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - get_it: ^4.0.2 - http: ">=0.12.1 <0.14.0" - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: provider_architecutre +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">2.2.2 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + provider: ^2.0.1 + get_it: + http: ^0.12.0+2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/010-provider-architecture/001-start/test/widget_test.dart b/010-provider-architecture/001-start/test/widget_test.dart index 00be119e..bcf5bc8d 100644 --- a/010-provider-architecture/001-start/test/widget_test.dart +++ b/010-provider-architecture/001-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:provider_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:provider_architecutre/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/010-provider-architecture/002-final-no-getit/.gitignore b/010-provider-architecture/002-final-no-getit/.gitignore new file mode 100644 index 00000000..07488ba6 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/.gitignore @@ -0,0 +1,70 @@ +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/010-provider-architecture/002-final-no-getit/.metadata b/010-provider-architecture/002-final-no-getit/.metadata new file mode 100644 index 00000000..101035a8 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/.metadata @@ -0,0 +1,10 @@ +# 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: fbe11671a4b78a707d9856588d956c0d3c39a6d5 + channel: master + +project_type: app diff --git a/010-provider-architecture/002-final-no-getit/.packages.generated b/010-provider-architecture/002-final-no-getit/.packages.generated new file mode 100644 index 00000000..8b7e8be9 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/.packages.generated @@ -0,0 +1,28 @@ +# Generated by pub on 2019-05-20 15:46:15.006980. +async:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/async-2.2.0/lib/ +boolean_selector:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/boolean_selector-1.0.4/lib/ +charcode:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/charcode-1.1.2/lib/ +collection:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/collection-1.14.11/lib/ +cupertino_icons:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-0.1.2/lib/ +flutter:file:///Users/remirousselet/dev/libs/flutter/packages/flutter/lib/ +flutter_test:file:///Users/remirousselet/dev/libs/flutter/packages/flutter_test/lib/ +functional_widget_annotation:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/functional_widget_annotation-0.5.1/lib/ +http:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/http-0.12.0+2/lib/ +http_parser:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/http_parser-3.1.3/lib/ +json_annotation:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/json_annotation-2.3.0/lib/ +matcher:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.5/lib/ +meta:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/meta-1.1.6/lib/ +path:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/path-1.6.2/lib/ +pedantic:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/pedantic-1.5.0/lib/ +provider:file:///Users/remirousselet/.pub-cache/git/provider-0d14fa454384a9e1a3810a1e2178c44f380fbc72/lib/ +quiver:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/quiver-2.0.3/lib/ +sky_engine:file:///Users/remirousselet/dev/libs/flutter/bin/cache/pkg/sky_engine/lib/ +source_span:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/source_span-1.5.5/lib/ +stack_trace:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.9.3/lib/ +stream_channel:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.0.0/lib/ +string_scanner:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.0.4/lib/ +term_glyph:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.1.0/lib/ +test_api:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.5/lib/ +typed_data:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/typed_data-1.1.6/lib/ +vector_math:file:///Users/remirousselet/.pub-cache/hosted/pub.dartlang.org/vector_math-2.0.8/lib/ +provider_architecutre:org-dartlang-app:/ diff --git a/010-provider-architecture/002-final-no-getit/README.md b/010-provider-architecture/002-final-no-getit/README.md new file mode 100644 index 00000000..2fad238f --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/README.md @@ -0,0 +1,5 @@ +# Pure Provider Architecture + +In this example the creator of the Provider package [Remi Rousselet](https://github.com/rrousselGit) gives us an example of how to remove get_it from the architecture and use the provider package only. + +The code is not complete, but it shows you the basic idea of how you can use proxy providers to setup service injection in your app using the provider package. \ No newline at end of file diff --git a/010-provider-architecture/002-final-no-getit/android/app/build.gradle b/010-provider-architecture/002-final-no-getit/android/app/build.gradle new file mode 100644 index 00000000..68680055 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.provider_architecutre" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/debug/AndroidManifest.xml b/010-provider-architecture/002-final-no-getit/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..83579b8e --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/AndroidManifest.xml b/010-provider-architecture/002-final-no-getit/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..36518eb8 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java b/010-provider-architecture/002-final-no-getit/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java new file mode 100644 index 00000000..ef4254d4 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.provider_architecutre; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/res/drawable/launch_background.xml b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/main/res/values/styles.xml b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/010-provider-architecture/002-final-no-getit/android/app/src/profile/AndroidManifest.xml b/010-provider-architecture/002-final-no-getit/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..83579b8e --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/010-provider-architecture/002-final-no-getit/android/build.gradle b/010-provider-architecture/002-final-no-getit/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/010-provider-architecture/002-final-no-getit/android/gradle.properties b/010-provider-architecture/002-final-no-getit/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/010-provider-architecture/002-final-no-getit/android/gradle/wrapper/gradle-wrapper.properties b/010-provider-architecture/002-final-no-getit/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/010-provider-architecture/002-final-no-getit/android/settings.gradle b/010-provider-architecture/002-final-no-getit/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/010-provider-architecture/002-final-no-getit/ios/Flutter/AppFrameworkInfo.plist b/010-provider-architecture/002-final-no-getit/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/010-provider-architecture/002-final-no-getit/ios/Flutter/Debug.xcconfig b/010-provider-architecture/002-final-no-getit/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/010-provider-architecture/002-final-no-getit/ios/Flutter/Release.xcconfig b/010-provider-architecture/002-final-no-getit/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/project.pbxproj b/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..e836bcfe --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner.xcworkspace/contents.xcworkspacedata b/010-provider-architecture/002-final-no-getit/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/AppDelegate.h b/010-provider-architecture/002-final-no-getit/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/AppDelegate.m b/010-provider-architecture/002-final-no-getit/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Base.lproj/LaunchScreen.storyboard b/010-provider-architecture/002-final-no-getit/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Base.lproj/Main.storyboard b/010-provider-architecture/002-final-no-getit/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/Info.plist b/010-provider-architecture/002-final-no-getit/ios/Runner/Info.plist new file mode 100644 index 00000000..55ae3953 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + provider_architecutre + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/010-provider-architecture/002-final-no-getit/ios/Runner/main.m b/010-provider-architecture/002-final-no-getit/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/012-provider-architecture-pt2/1-start/lib/core/enums/viewstate.dart b/010-provider-architecture/002-final-no-getit/lib/core/enums/viewstate.dart similarity index 100% rename from 012-provider-architecture-pt2/1-start/lib/core/enums/viewstate.dart rename to 010-provider-architecture/002-final-no-getit/lib/core/enums/viewstate.dart diff --git a/010-provider-architecture/002-final-no-getit/lib/core/models/comment.dart b/010-provider-architecture/002-final-no-getit/lib/core/models/comment.dart new file mode 100644 index 00000000..56ce4941 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/models/comment.dart @@ -0,0 +1,17 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'comment.g.dart'; + +@JsonSerializable() +class Comment { + final int postId; + final int id; + final String name; + final String email; + final String body; + + const Comment({this.postId, this.id, this.name, this.email, this.body}); + + factory Comment.fromJson(Map json) => _$CommentFromJson(json); + Map toJson() => _$CommentToJson(this); +} \ No newline at end of file diff --git a/010-provider-architecture/002-final-no-getit/lib/core/models/comment.g.dart b/010-provider-architecture/002-final-no-getit/lib/core/models/comment.g.dart new file mode 100644 index 00000000..9b1b1afc --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/models/comment.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'comment.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Comment _$CommentFromJson(Map json) { + return Comment( + postId: json['postId'] as int, + id: json['id'] as int, + name: json['name'] as String, + email: json['email'] as String, + body: json['body'] as String); +} + +Map _$CommentToJson(Comment instance) => { + 'postId': instance.postId, + 'id': instance.id, + 'name': instance.name, + 'email': instance.email, + 'body': instance.body + }; diff --git a/010-provider-architecture/002-final-no-getit/lib/core/models/post.dart b/010-provider-architecture/002-final-no-getit/lib/core/models/post.dart new file mode 100644 index 00000000..a65bd6dc --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/models/post.dart @@ -0,0 +1,16 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'post.g.dart'; + +@JsonSerializable() +class Post { + final int userId; + final int id; + final String title; + final String body; + + const Post({this.userId, this.id, this.title, this.body}); + + factory Post.fromJson(Map json) => _$PostFromJson(json); + Map toJson() => _$PostToJson(this); +} diff --git a/010-provider-architecture/002-final-no-getit/lib/core/models/post.g.dart b/010-provider-architecture/002-final-no-getit/lib/core/models/post.g.dart new file mode 100644 index 00000000..2829e400 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/models/post.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'post.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Post _$PostFromJson(Map json) { + return Post( + userId: json['userId'] as int, + id: json['id'] as int, + title: json['title'] as String, + body: json['body'] as String); +} + +Map _$PostToJson(Post instance) => { + 'userId': instance.userId, + 'id': instance.id, + 'title': instance.title, + 'body': instance.body + }; diff --git a/010-provider-architecture/002-final-no-getit/lib/core/models/user.dart b/010-provider-architecture/002-final-no-getit/lib/core/models/user.dart new file mode 100644 index 00000000..648405c6 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/models/user.dart @@ -0,0 +1,20 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'user.g.dart'; + +@JsonSerializable() +class User { + final int id; + final String name; + final String username; + + const User({this.id, this.name, this.username}); + + const User.initial() + : id = null, + name = '', + username = ''; + + factory User.fromJson(Map json) => _$UserFromJson(json); + Map toJson() => _$UserToJson(this); +} diff --git a/010-provider-architecture/002-final-no-getit/lib/core/models/user.g.dart b/010-provider-architecture/002-final-no-getit/lib/core/models/user.g.dart new file mode 100644 index 00000000..7ea4f1f6 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/models/user.g.dart @@ -0,0 +1,20 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'user.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +User _$UserFromJson(Map json) { + return User( + id: json['id'] as int, + name: json['name'] as String, + username: json['username'] as String); +} + +Map _$UserToJson(User instance) => { + 'id': instance.id, + 'name': instance.name, + 'username': instance.username + }; diff --git a/010-provider-architecture/002-final-no-getit/lib/core/services/api.dart b/010-provider-architecture/002-final-no-getit/lib/core/services/api.dart new file mode 100644 index 00000000..0e7c8d7d --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/services/api.dart @@ -0,0 +1,58 @@ +import 'dart:convert'; + +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/models/user.dart'; +import 'package:http/http.dart' as http; + +/// The service responsible for networking requests +class Api { + static const endpoint = 'https://jsonplaceholder.typicode.com'; + + final _client = new http.Client(); + + Future getUserProfile(int userId) async { + // Get user profile for id + var response = await _client.get('$endpoint/users/$userId'); + + // Convert and return + return User.fromJson(json.decode(response.body)); + } + + Future> getPostsForUser(int userId) async { + var posts = List(); + // Get user posts for id + var response = await _client.get('$endpoint/posts?userId=$userId'); + + // parse into List + var parsed = json.decode(response.body) as List; + + // loop and convert each item to Post + for (var post in parsed) { + posts.add(Post.fromJson(post)); + } + + return posts; + } + + Future> getCommentsForPost(int postId) async { + var comments = List(); + + // Get comments for post + var response = await _client.get('$endpoint/comments?postId=$postId'); + + // Parse into List + var parsed = json.decode(response.body) as List; + + // Loop and convert each item to a Comment + for (var comment in parsed) { + comments.add(Comment.fromJson(comment)); + } + + return comments; + } + + void dispose() { + _client.close(); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/core/services/authentication_service.dart b/010-provider-architecture/002-final-no-getit/lib/core/services/authentication_service.dart new file mode 100644 index 00000000..f378f781 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/services/authentication_service.dart @@ -0,0 +1,24 @@ +import 'dart:async'; + +import 'package:provider_architecutre/core/models/user.dart'; +import 'api.dart'; + +class AuthenticationService { + Api api; + + StreamController _userController = StreamController(); + Stream get user => _userController.stream; + + Future login(int userId) async { + var fetchedUser = await api.getUserProfile(userId); + var hasUser = fetchedUser != null; + if (hasUser) { + _userController.add(fetchedUser); + } + return hasUser; + } + + dispose() { + _userController.close(); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/base_model.dart b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/base_model.dart new file mode 100644 index 00000000..c40093a5 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/base_model.dart @@ -0,0 +1,13 @@ +import 'package:flutter/widgets.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; + +class BaseModel extends ChangeNotifier { + ViewState _state = ViewState.Idle; + + ViewState get state => _state; + + void setState(ViewState viewState) { + _state = viewState; + notifyListeners(); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/comments_model.dart b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/comments_model.dart new file mode 100644 index 00000000..8f8b25dd --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/comments_model.dart @@ -0,0 +1,35 @@ +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/core/services/api.dart'; +import 'base_model.dart'; + +class CommentsModel extends BaseModel { + Api _api; + Api get api => _api; + set api(Api api) { + _api = api; + notifyListeners(); + } + + int _postId; + int get postId => _postId; + set postId(int postId) { + if (postId != _postId) { + _postId = postId; + _fetchComments(postId); + notifyListeners(); + } + } + + List _comments; + List get comments => _comments; + + Future _fetchComments(int postId) async { + if (state == ViewState.Busy) { + throw StateError('already fetching'); + } + setState(ViewState.Busy); + _comments = await _api.getCommentsForPost(postId); + setState(ViewState.Idle); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/home_model.dart b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/home_model.dart new file mode 100644 index 00000000..016cdf1f --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/home_model.dart @@ -0,0 +1,36 @@ +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/services/api.dart'; + +import 'base_model.dart'; + +class HomeModel extends BaseModel { + Api _api; + Api get api => _api; + set api(Api api) { + _api = api; + notifyListeners(); + } + + int _userId; + int get userId => _userId; + set userId(int userId) { + if (_userId != userId) { + _userId = userId; + _getPosts(userId); + notifyListeners(); + } + } + + List posts = []; + + Future _getPosts(int userId) async { + if (state == ViewState.Busy) { + throw StateError( + "fetching posts again when the current request haven't finished"); + } + setState(ViewState.Busy); + posts = await _api.getPostsForUser(userId); + setState(ViewState.Idle); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/login_model.dart b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/login_model.dart new file mode 100644 index 00000000..62be11ae --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/core/viewmodels/login_model.dart @@ -0,0 +1,34 @@ +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/services/authentication_service.dart'; +import 'package:provider_architecutre/core/viewmodels/base_model.dart'; + +class LoginModel extends BaseModel { + AuthenticationService _authenticationService; + AuthenticationService get authenticationService => _authenticationService; + set authenticationService(AuthenticationService authenticationService) { + _authenticationService = authenticationService; + notifyListeners(); + } + + String errorMessage; + + Future login(String userIdText) async { + setState(ViewState.Busy); + + var userId = int.tryParse(userIdText); + + // Not a number + if (userId == null) { + errorMessage = 'Value entered is not a number'; + setState(ViewState.Idle); + return false; + } + + var success = await _authenticationService.login(userId); + + // Handle potential error here too. + + setState(ViewState.Idle); + return success; + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/main.dart b/010-provider-architecture/002-final-no-getit/lib/main.dart new file mode 100644 index 00000000..a2d6fcf2 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/main.dart @@ -0,0 +1,89 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/services/authentication_service.dart'; +import 'package:provider_architecutre/core/viewmodels/login_model.dart'; +import 'package:provider_architecutre/ui/router.dart'; +import 'package:provider_architecutre/ui/views/home_view.dart'; +import 'package:provider_architecutre/ui/views/login_view.dart'; + +import 'core/models/user.dart'; +import 'core/services/api.dart'; +import 'core/viewmodels/home_model.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MultiProvider( + providers: [ + Provider( + builder: (_) => Api(), + dispose: (_, api) => api.dispose(), + ), + ProxyProvider( + builder: (_, api, previous) => + (previous ?? AuthenticationService())..api = api, + dispose: (_, auth) => auth.dispose(), + ), + // TODO(rousselGit) change to StreamProxyProvider when available + ProxyProvider>.custom( + builder: (_, auth, __) => auth.user, + providerBuilder: (_, stream, child) { + return StreamProvider.value( + stream: stream, + initialData: User.initial(), + child: child, + ); + }, + ), + // TODO(rousselGit) change to ChangeNotifierProxyProvider2 when available + ProxyProvider.custom( + builder: (context, user, previous) => (previous ?? HomeModel()) + ..api = Provider.of(context) + ..userId = user?.id, + dispose: (_, model) => model.dispose(), + providerBuilder: (_, notifier, child) { + return ChangeNotifierProvider.value( + notifier: notifier, + child: child, + ); + }, + ), + ProxyProvider.custom( + builder: (_, auth, previous) => + (previous ?? LoginModel())..authenticationService = auth, + providerBuilder: (_, login, child) => + ChangeNotifierProvider.value( + notifier: login, + child: child, + ), + ) + ], + child: MaterialApp( + title: 'Flutter Demo', + routes: { + // `initialRoute` is not enough + // the route `/` will always be pushed. So `/` should handle displaying LoginView internally + // see https://stackoverflow.com/questions/56145378/why-is-initstate-called-twice/56145478#56145478 + '/': (context) => Provider.of(context)?.id != null + ? const HomeView() + : const LoginView(), + '/login': (_) => const LoginView(), + }, + onGenerateRoute: Router.generateRoute, + onUnknownRoute: (settings) => MaterialPageRoute( + builder: (_) => Scaffold( + body: Center( + child: Text('No route defined for ${settings.name}'), + ), + ), + ), + ), + ); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/router.dart b/010-provider-architecture/002-final-no-getit/lib/ui/router.dart new file mode 100644 index 00000000..3975202c --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/router.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/ui/views/post_view.dart'; + +class Router { + static Route generateRoute(RouteSettings settings) { + switch (settings.name) { + case '/post': + var post = settings.arguments as Post; + return MaterialPageRoute( + builder: (_) => Provider.value(value: post, child: PostView()), + ); + default: + return null; + } + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/shared/app_colors.dart b/010-provider-architecture/002-final-no-getit/lib/ui/shared/app_colors.dart new file mode 100644 index 00000000..76575901 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/shared/app_colors.dart @@ -0,0 +1,4 @@ +import 'package:flutter/material.dart'; + +const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); +const Color commentColor = Color.fromARGB(255, 255, 246, 196); diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/shared/text_styles.dart b/010-provider-architecture/002-final-no-getit/lib/ui/shared/text_styles.dart new file mode 100644 index 00000000..6847af85 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/shared/text_styles.dart @@ -0,0 +1,4 @@ +import 'package:flutter/material.dart'; + +const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); +const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); \ No newline at end of file diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/shared/ui_helpers.dart b/010-provider-architecture/002-final-no-getit/lib/ui/shared/ui_helpers.dart new file mode 100644 index 00000000..f9d5650b --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/shared/ui_helpers.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +/// Contains useful functions to reduce boilerplate code +class UIHelper { + // Vertical spacing constants. Adjust to your liking. + static const double _VerticalSpaceSmall = 10.0; + static const double _VerticalSpaceMedium = 20.0; + static const double _VerticalSpaceLarge = 60.0; + + // Vertical spacing constants. Adjust to your liking. + static const double _HorizontalSpaceSmall = 10.0; + static const double _HorizontalSpaceMedium = 20.0; + static const double HorizontalSpaceLarge = 60.0; + + /// Returns a vertical space with height set to [_VerticalSpaceSmall] + static Widget verticalSpaceSmall = SizedBox(width: _VerticalSpaceSmall); + + /// Returns a vertical space with height set to [_VerticalSpaceMedium] + static Widget verticalSpaceMedium() { + return verticalSpace(_VerticalSpaceMedium); + } + + /// Returns a vertical space with height set to [_VerticalSpaceLarge] + static const Widget verticalSpaceLarge = SizedBox(width: _VerticalSpaceLarge); + + /// Returns a vertical space equal to the [height] supplied + static Widget verticalSpace(double height) { + return Container(height: height); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceSmall] + static Widget horizontalSpaceSmall() { + return horizontalSpace(_HorizontalSpaceSmall); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceMedium] + static Widget horizontalSpaceMedium() { + return horizontalSpace(_HorizontalSpaceMedium); + } + + /// Returns a vertical space with height set to [HorizontalSpaceLarge] + static Widget horizontalSpaceLarge() { + return horizontalSpace(HorizontalSpaceLarge); + } + + /// Returns a vertical space equal to the [width] supplied + static Widget horizontalSpace(double width) { + return Container(width: width); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/views/base_view.dart b/010-provider-architecture/002-final-no-getit/lib/ui/views/base_view.dart new file mode 100644 index 00000000..94f8810c --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/views/base_view.dart @@ -0,0 +1,45 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/viewmodels/base_model.dart'; + +class BaseView extends StatefulWidget { + final Widget Function(BuildContext context, T model, Widget child) builder; + final Function(T) onModelReady; + final T model; + + BaseView({ + Key key, + this.builder, + this.onModelReady, + this.model, + }) : super(key: key); + + @override + _BaseViewState createState() => _BaseViewState(); +} + +class _BaseViewState extends State> { + @override + void initState() { + super.initState(); + if (widget.onModelReady != null) { + widget.onModelReady(widget.model); + } + } + + @override + void didUpdateWidget(BaseView oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.model != widget.model) { + widget.onModelReady(widget.model); + } + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider.value( + notifier: widget.model, + child: Consumer(builder: widget.builder), + ); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/views/home_view.dart b/010-provider-architecture/002-final-no-getit/lib/ui/views/home_view.dart new file mode 100644 index 00000000..ed8c10d9 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/views/home_view.dart @@ -0,0 +1,82 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/models/user.dart'; +import 'package:provider_architecutre/core/viewmodels/home_model.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/shared/text_styles.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; +import 'package:provider_architecutre/ui/widgets/postlist_item.dart'; +import 'package:functional_widget_annotation/functional_widget_annotation.dart'; + +part 'home_view.g.dart'; + +@widget +Widget homeView() { + return Scaffold( + backgroundColor: backgroundColor, + // A consumer so that we don't rebuild `Scaffold` when `HomeModel` change. + body: Consumer(builder: (context, model, _) { + return model.state == ViewState.Busy + ? const Center(child: CircularProgressIndicator()) + : const HomeContent( + header: HeaderTitle(), + body: PostList(), + ); + }), + ); +} + +// It's better as a standalone widget since it depends on `BuiltContext` +// so we don't rebuild `HomeContent` for no reason, and we have a const constructor +@widget +Widget headerTitle(BuildContext context) { + return Text( + 'Welcome ${Provider.of(context).name}', + style: headerStyle, + ); +} + +@widget +Widget homeContent({Widget body, Widget header}) { + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + UIHelper.verticalSpaceLarge, + Padding( + padding: const EdgeInsets.only(left: 20.0), + child: header, + ), + const Padding( + padding: const EdgeInsets.only(left: 20.0), + child: const Text( + 'Here are all your posts', + style: subHeaderStyle, + ), + ), + UIHelper.verticalSpaceSmall, + Expanded(child: body), + ], + ); +} + +@widget +Widget postList(BuildContext context) { + final homeModel = Provider.of(context); + + return ListView.builder( + itemCount: homeModel.posts.length, + itemBuilder: (context, index) { + var post = homeModel.posts[index]; + return Provider.value( + key: ValueKey(post.id), + value: post, + // it's not necessary to move the click handler to PostListItem + // but this allows to use a const constructor, which is better for performance. + // this way, only the item that changes rebuilds. Not the whole list. + child: const PostListItem(), + ); + }, + ); +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/views/home_view.g.dart b/010-provider-architecture/002-final-no-getit/lib/ui/views/home_view.g.dart new file mode 100644 index 00000000..586e80f9 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/views/home_view.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'home_view.dart'; + +// ************************************************************************** +// FunctionalWidgetGenerator +// ************************************************************************** + +class HomeView extends StatelessWidget { + const HomeView({Key key}) : super(key: key); + + @override + Widget build(BuildContext _context) => homeView(); +} + +class HeaderTitle extends StatelessWidget { + const HeaderTitle({Key key}) : super(key: key); + + @override + Widget build(BuildContext _context) => headerTitle(_context); +} + +class HomeContent extends StatelessWidget { + const HomeContent({Key key, this.body, this.header}) : super(key: key); + + final Widget body; + + final Widget header; + + @override + Widget build(BuildContext _context) => + homeContent(body: body, header: header); +} + +class PostList extends StatelessWidget { + const PostList({Key key}) : super(key: key); + + @override + Widget build(BuildContext _context) => postList(_context); +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/views/login_view.dart b/010-provider-architecture/002-final-no-getit/lib/ui/views/login_view.dart new file mode 100644 index 00000000..762650f1 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/views/login_view.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/viewmodels/login_model.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/widgets/login_header.dart'; + +class LoginView extends StatefulWidget { + const LoginView({Key key}) : super(key: key); + + @override + _LoginViewState createState() => _LoginViewState(); +} + +class _LoginViewState extends State { + final TextEditingController _controller = TextEditingController(); + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final model = Provider.of(context); + return Scaffold( + backgroundColor: backgroundColor, + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LoginHeader( + validationMessage: model.errorMessage, + controller: _controller, + ), + model.state == ViewState.Busy + ? const CircularProgressIndicator() + : FlatButton( + color: Colors.white, + child: const Text( + 'Login', + style: TextStyle(color: Colors.black), + ), + onPressed: () async { + var loginSuccess = await model.login(_controller.text); + if (loginSuccess) { + Navigator.pushNamed(context, '/'); + } + }, + ) + ], + ), + ); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/views/post_view.dart b/010-provider-architecture/002-final-no-getit/lib/ui/views/post_view.dart new file mode 100644 index 00000000..cedb4c5b --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/views/post_view.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/models/user.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/shared/text_styles.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; +import 'package:provider_architecutre/ui/widgets/comments.dart'; + +class PostView extends StatelessWidget { + @override + Widget build(BuildContext context) { + final post = Provider.of(context); + return Scaffold( + backgroundColor: backgroundColor, + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + UIHelper.verticalSpaceLarge, + Text(post.title, style: headerStyle), + Text( + 'by ${Provider.of(context).name}', + style: TextStyle(fontSize: 9.0), + ), + UIHelper.verticalSpaceMedium(), + Text(post.body), + const Comments(), + ], + ), + ), + ); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/widgets/comments.dart b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/comments.dart new file mode 100644 index 00000000..2705d37e --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/comments.dart @@ -0,0 +1,65 @@ +import 'package:flutter/material.dart'; +import 'package:functional_widget_annotation/functional_widget_annotation.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/viewmodels/comments_model.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; + +part 'comments.g.dart'; + +@widget +Widget comments(BuildContext context) { + // TODO(rrousselGit) refactor to ProxyChangeNotifierProvider2 when available + return ProxyProvider.custom( + builder: (context, post, previous) { + final model = previous ?? CommentsModel(); + model.api = Provider.of(context); + model.postId = post.id; + return model; + }, + providerBuilder: (_, model, child) => + ChangeNotifierProvider.value(notifier: model, child: child), + dispose: (_, model) => model.dispose(), + child: Consumer( + builder: (context, model, child) => model.state == ViewState.Busy + ? const Center(child: CircularProgressIndicator()) + : Expanded( + child: ListView.builder( + itemCount: model.comments.length, + itemBuilder: (context, index) { + return Provider.value( + value: model.comments[index], + child: const CommentItem(), + ); + }, + ), + ), + ), + ); +} + +/// Renders a single comment given a comment model +@widget +Widget commentItem(BuildContext context) { + final comment = Provider.of(context); + return Container( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.symmetric(vertical: 10.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: commentColor), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + comment.name, + style: TextStyle(fontWeight: FontWeight.bold), + ), + UIHelper.verticalSpaceSmall, + Text(comment.body), + ], + ), + ); +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/widgets/comments.g.dart b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/comments.g.dart new file mode 100644 index 00000000..23d2feee --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/comments.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'comments.dart'; + +// ************************************************************************** +// FunctionalWidgetGenerator +// ************************************************************************** + +class Comments extends StatelessWidget { + const Comments({Key key}) : super(key: key); + + @override + Widget build(BuildContext _context) => comments(_context); +} + +/// Renders a single comment given a comment model +class CommentItem extends StatelessWidget { + /// Renders a single comment given a comment model + const CommentItem({Key key}) : super(key: key); + + @override + Widget build(BuildContext _context) => commentItem(_context); +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/widgets/login_header.dart b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/login_header.dart new file mode 100644 index 00000000..394081d1 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/login_header.dart @@ -0,0 +1,44 @@ +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/ui/shared/text_styles.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; + +class LoginHeader extends StatelessWidget { + final TextEditingController controller; + final String validationMessage; + + LoginHeader({@required this.controller, this.validationMessage}); + + @override + Widget build(BuildContext context) { + return Column(children: [ + Text('Login', style: headerStyle), + UIHelper.verticalSpaceMedium(), + Text('Enter a number between 1 - 10', style: subHeaderStyle), + LoginTextField(controller), + this.validationMessage != null + ? Text(validationMessage, style: TextStyle(color: Colors.red)) + : Container() + ]); + } +} + +class LoginTextField extends StatelessWidget { + final TextEditingController controller; + + LoginTextField(this.controller); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 15.0), + margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), + height: 50.0, + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10.0)), + child: TextField( + decoration: InputDecoration.collapsed(hintText: 'User Id'), + controller: controller), + ); + } +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/widgets/postlist_item.dart b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/postlist_item.dart new file mode 100644 index 00000000..612c95fc --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/postlist_item.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:functional_widget_annotation/functional_widget_annotation.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/models/post.dart'; + +part 'postlist_item.g.dart'; + +// separation of design the data-binding +@widget +Widget postListItem(BuildContext context) { + final post = Provider.of(context); + return _PostListItem( + onTap: () { + Navigator.pushNamed(context, '/post', arguments: post); + }, + title: Text(post.title), + body: Text(post.body), + ); +} + +@widget +Widget _postListItem({Widget title, Widget body, VoidCallback onTap}) { + return GestureDetector( + onTap: onTap, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), + padding: EdgeInsets.all(10.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5.0), + boxShadow: [ + BoxShadow( + blurRadius: 3.0, + offset: Offset(0.0, 2.0), + color: Color.fromARGB(80, 0, 0, 0)) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DefaultTextStyle.merge( + child: title, + style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0), + ), + DefaultTextStyle.merge( + child: body, + maxLines: 2, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ); +} diff --git a/010-provider-architecture/002-final-no-getit/lib/ui/widgets/postlist_item.g.dart b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/postlist_item.g.dart new file mode 100644 index 00000000..beeba8d0 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/lib/ui/widgets/postlist_item.g.dart @@ -0,0 +1,29 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'postlist_item.dart'; + +// ************************************************************************** +// FunctionalWidgetGenerator +// ************************************************************************** + +class PostListItem extends StatelessWidget { + const PostListItem({Key key}) : super(key: key); + + @override + Widget build(BuildContext _context) => postListItem(_context); +} + +class _PostListItem extends StatelessWidget { + const _PostListItem({Key key, this.title, this.body, this.onTap}) + : super(key: key); + + final Widget title; + + final Widget body; + + final VoidCallback onTap; + + @override + Widget build(BuildContext _context) => + _postListItem(title: title, body: body, onTap: onTap); +} diff --git a/010-provider-architecture/002-final-no-getit/pubspec.lock b/010-provider-architecture/002-final-no-getit/pubspec.lock new file mode 100644 index 00000000..5816d2a7 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/pubspec.lock @@ -0,0 +1,183 @@ +# Generated by pub +# See https://www.dartlang.org/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + functional_widget_annotation: + dependency: "direct main" + description: + name: functional_widget_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.1" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.0+2" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + provider: + dependency: "direct main" + description: + path: "." + ref: proxy-provider + resolved-ref: "0d14fa454384a9e1a3810a1e2178c44f380fbc72" + url: "https://github.com/rrousselGit/provider" + source: git + version: "2.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.5" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" +sdks: + dart: ">2.2.2 <3.0.0" diff --git a/010-provider-architecture/002-final-no-getit/pubspec.yaml b/010-provider-architecture/002-final-no-getit/pubspec.yaml new file mode 100644 index 00000000..3a491916 --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/pubspec.yaml @@ -0,0 +1,29 @@ +name: provider_architecutre +description: A new Flutter project. +version: 1.0.0+1 + +environment: + sdk: '>2.2.2 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^0.1.2 + # TODO(rrousselGit) change to 2.1.0 when merged and deployed + provider: + git: + url: https://github.com/rrousselGit/provider + ref: proxy-provider + http: ^0.12.0+2 + functional_widget_annotation: + json_annotation: + +builders: + functional_widget: + json_serializable: + +dev_dependencies: + flutter_test: + sdk: flutter +flutter: + uses-material-design: true diff --git a/010-provider-architecture/002-final-no-getit/test/widget_test.dart b/010-provider-architecture/002-final-no-getit/test/widget_test.dart new file mode 100644 index 00000000..bcf5bc8d --- /dev/null +++ b/010-provider-architecture/002-final-no-getit/test/widget_test.dart @@ -0,0 +1,30 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:provider_architecutre/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/010-provider-architecture/002-final/.gitignore b/010-provider-architecture/002-final/.gitignore index 5be59a14..07488ba6 100644 --- a/010-provider-architecture/002-final/.gitignore +++ b/010-provider-architecture/002-final/.gitignore @@ -1,70 +1,70 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# 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/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/010-provider-architecture/002-final/.metadata b/010-provider-architecture/002-final/.metadata index b9fdc6b5..101035a8 100644 --- a/010-provider-architecture/002-final/.metadata +++ b/010-provider-architecture/002-final/.metadata @@ -1,10 +1,10 @@ -# 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: fbe11671a4b78a707d9856588d956c0d3c39a6d5 - channel: master - -project_type: app +# 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: fbe11671a4b78a707d9856588d956c0d3c39a6d5 + channel: master + +project_type: app diff --git a/010-provider-architecture/002-final/README.md b/010-provider-architecture/002-final/README.md index 2d408426..9625d15a 100644 --- a/010-provider-architecture/002-final/README.md +++ b/010-provider-architecture/002-final/README.md @@ -1,3 +1,3 @@ -# Provider + Get_it Architecture - +# Provider + Get_it Architecture + This is the final result of [this tutorial](https://www.filledstacks.com/post/flutter-architecture-my-provider-implementation-guide) where we setup a Flutter app architecture using the Provider package. \ No newline at end of file diff --git a/010-provider-architecture/002-final/android/app/build.gradle b/010-provider-architecture/002-final/android/app/build.gradle new file mode 100644 index 00000000..68680055 --- /dev/null +++ b/010-provider-architecture/002-final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.provider_architecutre" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/010-provider-architecture/002-final/android/app/src/debug/AndroidManifest.xml b/010-provider-architecture/002-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..83579b8e --- /dev/null +++ b/010-provider-architecture/002-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/010-provider-architecture/002-final/android/app/src/main/AndroidManifest.xml b/010-provider-architecture/002-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..36518eb8 --- /dev/null +++ b/010-provider-architecture/002-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java b/010-provider-architecture/002-final/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java new file mode 100644 index 00000000..ef4254d4 --- /dev/null +++ b/010-provider-architecture/002-final/android/app/src/main/java/com/example/provider_architecutre/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.provider_architecutre; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/010-provider-architecture/002-final/android/app/src/main/res/drawable/launch_background.xml b/010-provider-architecture/002-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/010-provider-architecture/002-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/010-provider-architecture/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/010-provider-architecture/002-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/010-provider-architecture/002-final/android/app/src/main/res/values/styles.xml b/010-provider-architecture/002-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/010-provider-architecture/002-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/010-provider-architecture/002-final/android/app/src/profile/AndroidManifest.xml b/010-provider-architecture/002-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..83579b8e --- /dev/null +++ b/010-provider-architecture/002-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/010-provider-architecture/002-final/android/build.gradle b/010-provider-architecture/002-final/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/010-provider-architecture/002-final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/010-provider-architecture/002-final/android/gradle.properties b/010-provider-architecture/002-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/010-provider-architecture/002-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/010-provider-architecture/002-final/android/gradle/wrapper/gradle-wrapper.properties b/010-provider-architecture/002-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/010-provider-architecture/002-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/010-provider-architecture/002-final/android/settings.gradle b/010-provider-architecture/002-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/010-provider-architecture/002-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/010-provider-architecture/002-final/ios/Flutter/AppFrameworkInfo.plist b/010-provider-architecture/002-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/010-provider-architecture/002-final/ios/Flutter/Debug.xcconfig b/010-provider-architecture/002-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/010-provider-architecture/002-final/ios/Flutter/Release.xcconfig b/010-provider-architecture/002-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/010-provider-architecture/002-final/ios/Runner.xcodeproj/project.pbxproj b/010-provider-architecture/002-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..e836bcfe --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.providerArchitecutre; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/010-provider-architecture/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/010-provider-architecture/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/010-provider-architecture/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/010-provider-architecture/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/010-provider-architecture/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/010-provider-architecture/002-final/ios/Runner/AppDelegate.h b/010-provider-architecture/002-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/010-provider-architecture/002-final/ios/Runner/AppDelegate.m b/010-provider-architecture/002-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/010-provider-architecture/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/010-provider-architecture/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final/ios/Runner/Base.lproj/Main.storyboard b/010-provider-architecture/002-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/010-provider-architecture/002-final/ios/Runner/Info.plist b/010-provider-architecture/002-final/ios/Runner/Info.plist new file mode 100644 index 00000000..55ae3953 --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + provider_architecutre + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/010-provider-architecture/002-final/ios/Runner/main.m b/010-provider-architecture/002-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/010-provider-architecture/002-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/010-provider-architecture/002-final/lib/core/models/comment.dart b/010-provider-architecture/002-final/lib/core/models/comment.dart index 6a2ebec8..2984f6f4 100644 --- a/010-provider-architecture/002-final/lib/core/models/comment.dart +++ b/010-provider-architecture/002-final/lib/core/models/comment.dart @@ -1,27 +1,27 @@ -class Comment { - int postId; - int id; - String name; - String email; - String body; - - Comment({this.postId, this.id, this.name, this.email, this.body}); - - Comment.fromJson(Map json) { - postId = json['postId']; - id = json['id']; - name = json['name']; - email = json['email']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['postId'] = this.postId; - data['id'] = this.id; - data['name'] = this.name; - data['email'] = this.email; - data['body'] = this.body; - return data; - } +class Comment { + int postId; + int id; + String name; + String email; + String body; + + Comment({this.postId, this.id, this.name, this.email, this.body}); + + Comment.fromJson(Map json) { + postId = json['postId']; + id = json['id']; + name = json['name']; + email = json['email']; + body = json['body']; + } + + Map toJson() { + final Map data = new Map(); + data['postId'] = this.postId; + data['id'] = this.id; + data['name'] = this.name; + data['email'] = this.email; + data['body'] = this.body; + return data; + } } \ No newline at end of file diff --git a/010-provider-architecture/002-final/lib/core/models/post.dart b/010-provider-architecture/002-final/lib/core/models/post.dart index c1c6cf92..845a19c9 100644 --- a/010-provider-architecture/002-final/lib/core/models/post.dart +++ b/010-provider-architecture/002-final/lib/core/models/post.dart @@ -1,24 +1,24 @@ -class Post { - int userId; - int id; - String title; - String body; - - Post({this.userId, this.id, this.title, this.body}); - - Post.fromJson(Map json) { - userId = json['userId']; - id = json['id']; - title = json['title']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['id'] = this.id; - data['title'] = this.title; - data['body'] = this.body; - return data; - } +class Post { + int userId; + int id; + String title; + String body; + + Post({this.userId, this.id, this.title, this.body}); + + Post.fromJson(Map json) { + userId = json['userId']; + id = json['id']; + title = json['title']; + body = json['body']; + } + + Map toJson() { + final Map data = new Map(); + data['userId'] = this.userId; + data['id'] = this.id; + data['title'] = this.title; + data['body'] = this.body; + return data; + } } \ No newline at end of file diff --git a/010-provider-architecture/002-final/lib/core/models/user.dart b/010-provider-architecture/002-final/lib/core/models/user.dart index 1071dc6c..4a620651 100644 --- a/010-provider-architecture/002-final/lib/core/models/user.dart +++ b/010-provider-architecture/002-final/lib/core/models/user.dart @@ -1,25 +1,25 @@ -class User { - int id; - String name; - String username; - User({this.id, this.name, this.username}); - - User.initial() - : id = 0, - name = '', - username = ''; - - User.fromJson(Map json) { - id = json['id']; - name = json['name']; - username = json['username']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['username'] = this.username; - return data; - } -} +class User { + int id; + String name; + String username; + User({this.id, this.name, this.username}); + + User.initial() + : id = 0, + name = '', + username = ''; + + User.fromJson(Map json) { + id = json['id']; + name = json['name']; + username = json['username']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['username'] = this.username; + return data; + } +} diff --git a/010-provider-architecture/002-final/lib/core/services/api.dart b/010-provider-architecture/002-final/lib/core/services/api.dart index 137f92b2..17b4aeb4 100644 --- a/010-provider-architecture/002-final/lib/core/services/api.dart +++ b/010-provider-architecture/002-final/lib/core/services/api.dart @@ -1,54 +1,54 @@ -import 'dart:convert'; - -import 'package:provider_architecture/core/models/comment.dart'; -import 'package:provider_architecture/core/models/post.dart'; -import 'package:provider_architecture/core/models/user.dart'; -import 'package:http/http.dart' as http; - -/// The service responsible for networking requests -class Api { - static const endpoint = 'https://jsonplaceholder.typicode.com'; - - var client = new http.Client(); - - Future getUserProfile(int userId) async { - // Get user profile for id - var response = await client.get('$endpoint/users/$userId'); - - // Convert and return - return User.fromJson(json.decode(response.body)); - } - - Future> getPostsForUser(int userId) async { - var posts = List(); - // Get user posts for id - var response = await client.get('$endpoint/posts?userId=$userId'); - - // parse into List - var parsed = json.decode(response.body) as List; - - // loop and convert each item to Post - for (var post in parsed) { - posts.add(Post.fromJson(post)); - } - - return posts; - } - - Future> getCommentsForPost(int postId) async { - var comments = List(); - - // Get comments for post - var response = await client.get('$endpoint/comments?postId=$postId'); - - // Parse into List - var parsed = json.decode(response.body) as List; - - // Loop and convert each item to a Comment - for (var comment in parsed) { - comments.add(Comment.fromJson(comment)); - } - - return comments; - } -} +import 'dart:convert'; + +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/models/user.dart'; +import 'package:http/http.dart' as http; + +/// The service responsible for networking requests +class Api { + static const endpoint = 'https://jsonplaceholder.typicode.com'; + + var client = new http.Client(); + + Future getUserProfile(int userId) async { + // Get user profile for id + var response = await client.get('$endpoint/users/$userId'); + + // Convert and return + return User.fromJson(json.decode(response.body)); + } + + Future> getPostsForUser(int userId) async { + var posts = List(); + // Get user posts for id + var response = await client.get('$endpoint/posts?userId=$userId'); + + // parse into List + var parsed = json.decode(response.body) as List; + + // loop and convert each item to Post + for (var post in parsed) { + posts.add(Post.fromJson(post)); + } + + return posts; + } + + Future> getCommentsForPost(int postId) async { + var comments = List(); + + // Get comments for post + var response = await client.get('$endpoint/comments?postId=$postId'); + + // Parse into List + var parsed = json.decode(response.body) as List; + + // Loop and convert each item to a Comment + for (var comment in parsed) { + comments.add(Comment.fromJson(comment)); + } + + return comments; + } +} diff --git a/010-provider-architecture/002-final/lib/core/services/authentication_service.dart b/010-provider-architecture/002-final/lib/core/services/authentication_service.dart index 00119764..cb5c2bea 100644 --- a/010-provider-architecture/002-final/lib/core/services/authentication_service.dart +++ b/010-provider-architecture/002-final/lib/core/services/authentication_service.dart @@ -1,23 +1,23 @@ -import 'dart:async'; - -import 'package:provider_architecture/core/models/user.dart'; - -import '../../locator.dart'; -import 'api.dart'; - -class AuthenticationService { - Api _api = locator(); - - StreamController userController = StreamController(); - - Future login(int userId) async { - var fetchedUser = await _api.getUserProfile(userId); - - var hasUser = fetchedUser != null; - if(hasUser) { - userController.add(fetchedUser); - } - - return hasUser; - } +import 'dart:async'; + +import 'package:provider_architecutre/core/models/user.dart'; + +import '../../locator.dart'; +import 'api.dart'; + +class AuthenticationService { + Api _api = locator(); + + StreamController userController = StreamController(); + + Future login(int userId) async { + var fetchedUser = await _api.getUserProfile(userId); + + var hasUser = fetchedUser != null; + if(hasUser) { + userController.add(fetchedUser); + } + + return hasUser; + } } \ No newline at end of file diff --git a/010-provider-architecture/002-final/lib/core/viewmodels/base_model.dart b/010-provider-architecture/002-final/lib/core/viewmodels/base_model.dart index 09e046a0..c40093a5 100644 --- a/010-provider-architecture/002-final/lib/core/viewmodels/base_model.dart +++ b/010-provider-architecture/002-final/lib/core/viewmodels/base_model.dart @@ -1,13 +1,13 @@ -import 'package:flutter/widgets.dart'; -import 'package:provider_architecture/core/enums/viewstate.dart'; - -class BaseModel extends ChangeNotifier { - ViewState _state = ViewState.Idle; - - ViewState get state => _state; - - void setState(ViewState viewState) { - _state = viewState; - notifyListeners(); - } -} +import 'package:flutter/widgets.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; + +class BaseModel extends ChangeNotifier { + ViewState _state = ViewState.Idle; + + ViewState get state => _state; + + void setState(ViewState viewState) { + _state = viewState; + notifyListeners(); + } +} diff --git a/010-provider-architecture/002-final/lib/core/viewmodels/comments_model.dart b/010-provider-architecture/002-final/lib/core/viewmodels/comments_model.dart index 27099954..1517a537 100644 --- a/010-provider-architecture/002-final/lib/core/viewmodels/comments_model.dart +++ b/010-provider-architecture/002-final/lib/core/viewmodels/comments_model.dart @@ -1,18 +1,18 @@ -import 'package:provider_architecture/core/enums/viewstate.dart'; -import 'package:provider_architecture/core/models/comment.dart'; -import 'package:provider_architecture/core/services/api.dart'; - -import '../../locator.dart'; -import 'base_model.dart'; - -class CommentsModel extends BaseModel { - Api _api = locator(); - - List comments; - - Future fetchComments(int postId) async { - setState(ViewState.Busy); - comments = await _api.getCommentsForPost(postId); - setState(ViewState.Idle); - } -} +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/core/services/api.dart'; + +import '../../locator.dart'; +import 'base_model.dart'; + +class CommentsModel extends BaseModel { + Api _api = locator(); + + List comments; + + Future fetchComments(int postId) async { + setState(ViewState.Busy); + comments = await _api.getCommentsForPost(postId); + setState(ViewState.Idle); + } +} diff --git a/010-provider-architecture/002-final/lib/core/viewmodels/home_model.dart b/010-provider-architecture/002-final/lib/core/viewmodels/home_model.dart index d9dab8c7..0d76cef2 100644 --- a/010-provider-architecture/002-final/lib/core/viewmodels/home_model.dart +++ b/010-provider-architecture/002-final/lib/core/viewmodels/home_model.dart @@ -1,18 +1,18 @@ -import 'package:provider_architecture/core/enums/viewstate.dart'; -import 'package:provider_architecture/core/models/post.dart'; -import 'package:provider_architecture/core/services/api.dart'; -import 'package:provider_architecture/locator.dart'; - -import 'base_model.dart'; - -class HomeModel extends BaseModel { - Api _api = locator(); - - List posts; - - Future getPosts(int userId) async { - setState(ViewState.Busy); - posts = await _api.getPostsForUser(userId); - setState(ViewState.Idle); - } +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/services/api.dart'; +import 'package:provider_architecutre/locator.dart'; + +import 'base_model.dart'; + +class HomeModel extends BaseModel { + Api _api = locator(); + + List posts; + + Future getPosts(int userId) async { + setState(ViewState.Busy); + posts = await _api.getPostsForUser(userId); + setState(ViewState.Idle); + } } \ No newline at end of file diff --git a/010-provider-architecture/002-final/lib/core/viewmodels/login_model.dart b/010-provider-architecture/002-final/lib/core/viewmodels/login_model.dart index 90e0c8b2..00069ac1 100644 --- a/010-provider-architecture/002-final/lib/core/viewmodels/login_model.dart +++ b/010-provider-architecture/002-final/lib/core/viewmodels/login_model.dart @@ -1,31 +1,31 @@ -import 'package:provider_architecture/core/enums/viewstate.dart'; -import 'package:provider_architecture/core/services/authentication_service.dart'; -import 'package:provider_architecture/core/viewmodels/base_model.dart'; - -import '../../locator.dart'; - -class LoginModel extends BaseModel { - final AuthenticationService _authenticationService = locator(); - - String errorMessage; - - Future login(String userIdText) async { - setState(ViewState.Busy); - - var userId = int.tryParse(userIdText); - - // Not a number - if(userId == null) { - errorMessage = 'Value entered is not a number'; - setState(ViewState.Idle); - return false; - } - - var success = await _authenticationService.login(userId); - - // Handle potential error here too. - - setState(ViewState.Idle); - return success; - } -} +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/services/authentication_service.dart'; +import 'package:provider_architecutre/core/viewmodels/base_model.dart'; + +import '../../locator.dart'; + +class LoginModel extends BaseModel { + final AuthenticationService _authenticationService = locator(); + + String errorMessage; + + Future login(String userIdText) async { + setState(ViewState.Busy); + + var userId = int.tryParse(userIdText); + + // Not a number + if(userId == null) { + errorMessage = 'Value entered is not a number'; + setState(ViewState.Idle); + return false; + } + + var success = await _authenticationService.login(userId); + + // Handle potential error here too. + + setState(ViewState.Idle); + return success; + } +} diff --git a/010-provider-architecture/002-final/lib/locator.dart b/010-provider-architecture/002-final/lib/locator.dart index b1eeac2a..372de9e0 100644 --- a/010-provider-architecture/002-final/lib/locator.dart +++ b/010-provider-architecture/002-final/lib/locator.dart @@ -1,18 +1,18 @@ -import 'package:get_it/get_it.dart'; - -import 'core/services/api.dart'; -import 'core/services/authentication_service.dart'; -import 'core/viewmodels/comments_model.dart'; -import 'core/viewmodels/home_model.dart'; -import 'core/viewmodels/login_model.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => Api()); - - locator.registerFactory(() => LoginModel()); - locator.registerFactory(() => HomeModel()); - locator.registerFactory(() => CommentsModel()); -} +import 'package:get_it/get_it.dart'; + +import 'core/services/api.dart'; +import 'core/services/authentication_service.dart'; +import 'core/viewmodels/comments_model.dart'; +import 'core/viewmodels/home_model.dart'; +import 'core/viewmodels/login_model.dart'; + +GetIt locator = GetIt(); + +void setupLocator() { + locator.registerLazySingleton(() => AuthenticationService()); + locator.registerLazySingleton(() => Api()); + + locator.registerLazySingleton(() => LoginModel()); + locator.registerFactory(() => HomeModel()); + locator.registerFactory(() => CommentsModel()); +} diff --git a/010-provider-architecture/002-final/lib/main.dart b/010-provider-architecture/002-final/lib/main.dart index 5b2b2bd4..2de5ca92 100644 --- a/010-provider-architecture/002-final/lib/main.dart +++ b/010-provider-architecture/002-final/lib/main.dart @@ -1,29 +1,28 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecture/core/services/authentication_service.dart'; -import 'package:provider_architecture/locator.dart'; -import 'package:provider_architecture/ui/router.dart'; - -import 'core/models/user.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return StreamProvider( - initialData: User.initial(), - create: (BuildContext context) => - locator().userController.stream, - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData(), - initialRoute: 'login', - onGenerateRoute: Router.generateRoute, - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/services/authentication_service.dart'; +import 'package:provider_architecutre/locator.dart'; +import 'package:provider_architecutre/ui/router.dart'; + +import 'core/models/user.dart'; + +void main() { + setupLocator(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return StreamProvider( + initialData: User.initial(), + builder: (context) => locator().userController, + child: MaterialApp( + title: 'Flutter Demo', + theme: ThemeData(), + initialRoute: '/login', + onGenerateRoute: Router.generateRoute, + ), + ); + } +} diff --git a/010-provider-architecture/002-final/lib/ui/router.dart b/010-provider-architecture/002-final/lib/ui/router.dart index 5e1285e4..36110713 100644 --- a/010-provider-architecture/002-final/lib/ui/router.dart +++ b/010-provider-architecture/002-final/lib/ui/router.dart @@ -1,29 +1,27 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider_architecture/core/models/post.dart'; -import 'package:provider_architecture/ui/views/home_view.dart'; -import 'package:provider_architecture/ui/views/login_view.dart'; -import 'package:provider_architecture/ui/views/post_view.dart'; - -const String initialRoute = "login"; - -class Router { - static Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case '/': - return MaterialPageRoute(builder: (_) => HomeView()); - case 'login': - return MaterialPageRoute(builder: (_) => LoginView()); - case 'post': - var post = settings.arguments as Post; - return MaterialPageRoute(builder: (_) => PostView(post: post)); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}'), - ), - )); - } - } -} +import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/ui/views/home_view.dart'; +import 'package:provider_architecutre/ui/views/login_view.dart'; +import 'package:provider_architecutre/ui/views/post_view.dart'; + +class Router { + static Route generateRoute(RouteSettings settings) { + switch (settings.name) { + case '/': + return MaterialPageRoute(builder: (_) => HomeView()); + case '/login': + return MaterialPageRoute(builder: (_) => LoginView()); + case '/post': + var post = settings.arguments as Post; + return MaterialPageRoute(builder: (_) => PostView(post: post)); + default: + return MaterialPageRoute( + builder: (_) => Scaffold( + body: Center( + child: Text('No route defined for ${settings.name}'), + ), + )); + } + } +} diff --git a/010-provider-architecture/002-final/lib/ui/shared/app_colors.dart b/010-provider-architecture/002-final/lib/ui/shared/app_colors.dart index 43ad166d..76575901 100644 --- a/010-provider-architecture/002-final/lib/ui/shared/app_colors.dart +++ b/010-provider-architecture/002-final/lib/ui/shared/app_colors.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; - -const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); -const Color commentColor = Color.fromARGB(255, 255, 246, 196); +import 'package:flutter/material.dart'; + +const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); +const Color commentColor = Color.fromARGB(255, 255, 246, 196); diff --git a/010-provider-architecture/002-final/lib/ui/shared/text_styles.dart b/010-provider-architecture/002-final/lib/ui/shared/text_styles.dart index 86fec3eb..6847af85 100644 --- a/010-provider-architecture/002-final/lib/ui/shared/text_styles.dart +++ b/010-provider-architecture/002-final/lib/ui/shared/text_styles.dart @@ -1,4 +1,4 @@ -import 'package:flutter/material.dart'; - -const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); +import 'package:flutter/material.dart'; + +const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); \ No newline at end of file diff --git a/010-provider-architecture/002-final/lib/ui/shared/ui_helpers.dart b/010-provider-architecture/002-final/lib/ui/shared/ui_helpers.dart index 0259d89b..925640e1 100644 --- a/010-provider-architecture/002-final/lib/ui/shared/ui_helpers.dart +++ b/010-provider-architecture/002-final/lib/ui/shared/ui_helpers.dart @@ -1,54 +1,54 @@ -import 'package:flutter/material.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 10.0; - static const double _VerticalSpaceMedium = 20.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 10.0; - static const double _HorizontalSpaceMedium = 20.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } -} +import 'package:flutter/material.dart'; + +/// Contains useful functions to reduce boilerplate code +class UIHelper { + // Vertical spacing constants. Adjust to your liking. + static const double _VerticalSpaceSmall = 10.0; + static const double _VerticalSpaceMedium = 20.0; + static const double _VerticalSpaceLarge = 60.0; + + // Vertical spacing constants. Adjust to your liking. + static const double _HorizontalSpaceSmall = 10.0; + static const double _HorizontalSpaceMedium = 20.0; + static const double HorizontalSpaceLarge = 60.0; + + /// Returns a vertical space with height set to [_VerticalSpaceSmall] + static Widget verticalSpaceSmall() { + return verticalSpace(_VerticalSpaceSmall); + } + + /// Returns a vertical space with height set to [_VerticalSpaceMedium] + static Widget verticalSpaceMedium() { + return verticalSpace(_VerticalSpaceMedium); + } + + /// Returns a vertical space with height set to [_VerticalSpaceLarge] + static Widget verticalSpaceLarge() { + return verticalSpace(_VerticalSpaceLarge); + } + + /// Returns a vertical space equal to the [height] supplied + static Widget verticalSpace(double height) { + return Container(height: height); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceSmall] + static Widget horizontalSpaceSmall() { + return horizontalSpace(_HorizontalSpaceSmall); + } + + /// Returns a vertical space with height set to [_HorizontalSpaceMedium] + static Widget horizontalSpaceMedium() { + return horizontalSpace(_HorizontalSpaceMedium); + } + + /// Returns a vertical space with height set to [HorizontalSpaceLarge] + static Widget horizontalSpaceLarge() { + return horizontalSpace(HorizontalSpaceLarge); + } + + /// Returns a vertical space equal to the [width] supplied + static Widget horizontalSpace(double width) { + return Container(width: width); + } +} diff --git a/010-provider-architecture/002-final/lib/ui/views/base_view.dart b/010-provider-architecture/002-final/lib/ui/views/base_view.dart index 46176637..6eb01d90 100644 --- a/010-provider-architecture/002-final/lib/ui/views/base_view.dart +++ b/010-provider-architecture/002-final/lib/ui/views/base_view.dart @@ -1,34 +1,34 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecture/core/viewmodels/base_model.dart'; - -import '../../locator.dart'; - -class BaseView extends StatefulWidget { - final Widget Function(BuildContext context, T model, Widget child) builder; - final Function(T) onModelReady; - - BaseView({this.builder, this.onModelReady}); - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T model = locator(); - - @override - void initState() { - if (widget.onModelReady != null) { - widget.onModelReady(model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => model, - child: Consumer(builder: widget.builder)); - } -} +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/viewmodels/base_model.dart'; + +import '../../locator.dart'; + +class BaseView extends StatefulWidget { + final Widget Function(BuildContext context, T model, Widget child) builder; + final Function(T) onModelReady; + + BaseView({this.builder, this.onModelReady}); + + @override + _BaseViewState createState() => _BaseViewState(); +} + +class _BaseViewState extends State> { + T model = locator(); + + @override + void initState() { + if (widget.onModelReady != null) { + widget.onModelReady(model); + } + super.initState(); + } + + @override + Widget build(BuildContext context) { + return ChangeNotifierProvider( + builder: (context) => model, + child: Consumer(builder: widget.builder)); + } +} diff --git a/010-provider-architecture/002-final/lib/ui/views/home_view.dart b/010-provider-architecture/002-final/lib/ui/views/home_view.dart index 2663d69a..e9d72ddc 100644 --- a/010-provider-architecture/002-final/lib/ui/views/home_view.dart +++ b/010-provider-architecture/002-final/lib/ui/views/home_view.dart @@ -1,53 +1,53 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecture/core/enums/viewstate.dart'; -import 'package:provider_architecture/core/models/post.dart'; -import 'package:provider_architecture/core/models/user.dart'; -import 'package:provider_architecture/core/viewmodels/home_model.dart'; -import 'package:provider_architecture/ui/shared/app_colors.dart'; -import 'package:provider_architecture/ui/shared/text_styles.dart'; -import 'package:provider_architecture/ui/shared/ui_helpers.dart'; -import 'package:provider_architecture/ui/widgets/postlist_item.dart'; - -import 'base_view.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getPosts(Provider.of(context).id), - builder: (context, model, child) => Scaffold( - backgroundColor: backgroundColor, - body: model.state == ViewState.Busy - ? Center(child: CircularProgressIndicator()) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge(), - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text('Welcome ${Provider.of(context).name}', - style: headerStyle,), - ), - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text('Here are all your posts', - style: subHeaderStyle), - ), - UIHelper.verticalSpaceSmall(), - Expanded(child: getPostsUi(model.posts)), - ],) - ), - ); - } - - Widget getPostsUi(List posts) => ListView.builder( - itemCount: posts.length, - itemBuilder: (context, index) => PostListItem( - post: posts[index], - onTap: () { - Navigator.pushNamed(context, 'post', arguments: posts[index]); - }, - ) - ); -} +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/models/user.dart'; +import 'package:provider_architecutre/core/viewmodels/home_model.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/shared/text_styles.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; +import 'package:provider_architecutre/ui/widgets/postlist_item.dart'; + +import 'base_view.dart'; + +class HomeView extends StatelessWidget { + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.getPosts(Provider.of(context).id), + builder: (context, model, child) => Scaffold( + backgroundColor: backgroundColor, + body: model.state == ViewState.Busy + ? Center(child: CircularProgressIndicator()) + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + UIHelper.verticalSpaceLarge(), + Padding( + padding: const EdgeInsets.only(left: 20.0), + child: Text('Welcome ${Provider.of(context).name}', + style: headerStyle,), + ), + Padding( + padding: const EdgeInsets.only(left: 20.0), + child: Text('Here are all your posts', + style: subHeaderStyle), + ), + UIHelper.verticalSpaceSmall(), + Expanded(child: getPostsUi(model.posts)), + ],) + ), + ); + } + + Widget getPostsUi(List posts) => ListView.builder( + itemCount: posts.length, + itemBuilder: (context, index) => PostListItem( + post: posts[index], + onTap: () { + Navigator.pushNamed(context, '/post', arguments: posts[index]); + }, + ) + ); +} diff --git a/010-provider-architecture/002-final/lib/ui/views/login_view.dart b/010-provider-architecture/002-final/lib/ui/views/login_view.dart index e1e6b51c..b3a2c5d7 100644 --- a/010-provider-architecture/002-final/lib/ui/views/login_view.dart +++ b/010-provider-architecture/002-final/lib/ui/views/login_view.dart @@ -1,42 +1,47 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/core/enums/viewstate.dart'; -import 'package:provider_architecture/core/viewmodels/login_model.dart'; -import 'package:provider_architecture/ui/shared/app_colors.dart'; -import 'package:provider_architecture/ui/widgets/login_header.dart'; - -import 'base_view.dart'; - -class LoginView extends StatelessWidget { - final TextEditingController _controller = TextEditingController(); - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, model, child) => Scaffold( - backgroundColor: backgroundColor, - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - LoginHeader( - validationMessage: model.errorMessage, controller: _controller), - model.state == ViewState.Busy - ? CircularProgressIndicator() - : FlatButton( - color: Colors.white, - child: Text( - 'Login', - style: TextStyle(color: Colors.black), - ), - onPressed: () async { - var loginSuccess = await model.login(_controller.text); - if (loginSuccess) { - Navigator.pushNamed(context, '/'); - } - }, - ) - ], - ), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/viewmodels/login_model.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/widgets/login_header.dart'; + +import 'base_view.dart'; + +class LoginView extends StatefulWidget { + @override + _LoginViewState createState() => _LoginViewState(); +} + +class _LoginViewState extends State { + final TextEditingController _controller = TextEditingController(); + + @override + Widget build(BuildContext context) { + return BaseView( + builder: (context, model, child) => Scaffold( + backgroundColor: backgroundColor, + body: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + LoginHeader( + validationMessage: model.errorMessage, + controller: _controller), + model.state == ViewState.Busy + ? CircularProgressIndicator() + : FlatButton( + color: Colors.white, + child: Text( + 'Login', + style: TextStyle(color: Colors.black), + ), + onPressed: () async { + var loginSuccess = await model.login(_controller.text); + if(loginSuccess){ + Navigator.pushNamed(context, '/'); + } + }, + ) + ],), + ), + ); + } +} diff --git a/010-provider-architecture/002-final/lib/ui/views/post_view.dart b/010-provider-architecture/002-final/lib/ui/views/post_view.dart index 506814e5..e1ab79ed 100644 --- a/010-provider-architecture/002-final/lib/ui/views/post_view.dart +++ b/010-provider-architecture/002-final/lib/ui/views/post_view.dart @@ -1,37 +1,37 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecture/core/models/post.dart'; -import 'package:provider_architecture/core/models/user.dart'; -import 'package:provider_architecture/ui/shared/app_colors.dart'; -import 'package:provider_architecture/ui/shared/text_styles.dart'; -import 'package:provider_architecture/ui/shared/ui_helpers.dart'; -import 'package:provider_architecture/ui/widgets/comments.dart'; - -class PostView extends StatelessWidget { - final Post post; - PostView({this.post}); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge(), - Text(post.title, style: headerStyle), - Text( - 'by ${Provider.of(context).name}', - style: TextStyle(fontSize: 9.0), - ), - UIHelper.verticalSpaceMedium(), - Text(post.body), - Comments(post.id) - ], - ), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:provider_architecutre/core/models/post.dart'; +import 'package:provider_architecutre/core/models/user.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/shared/text_styles.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; +import 'package:provider_architecutre/ui/widgets/comments.dart'; + +class PostView extends StatelessWidget { + final Post post; + PostView({this.post}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: backgroundColor, + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + UIHelper.verticalSpaceLarge(), + Text(post.title, style: headerStyle), + Text( + 'by ${Provider.of(context).name}', + style: TextStyle(fontSize: 9.0), + ), + UIHelper.verticalSpaceMedium(), + Text(post.body), + Comments(post.id) + ], + ), + ), + ); + } +} diff --git a/010-provider-architecture/002-final/lib/ui/widgets/comments.dart b/010-provider-architecture/002-final/lib/ui/widgets/comments.dart index 3350de32..4ff86025 100644 --- a/010-provider-architecture/002-final/lib/ui/widgets/comments.dart +++ b/010-provider-architecture/002-final/lib/ui/widgets/comments.dart @@ -1,52 +1,52 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/core/enums/viewstate.dart'; -import 'package:provider_architecture/core/models/comment.dart'; -import 'package:provider_architecture/core/viewmodels/comments_model.dart'; -import 'package:provider_architecture/ui/shared/app_colors.dart'; -import 'package:provider_architecture/ui/shared/ui_helpers.dart'; -import 'package:provider_architecture/ui/views/base_view.dart'; - -class Comments extends StatelessWidget { - final int postId; - Comments(this.postId); - - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.fetchComments(postId), - builder: (context, model, child) => model.state == ViewState.Busy - ? Center(child: CircularProgressIndicator()) - : Expanded(child: ListView( - children: model.comments - .map((comment) => CommentItem(comment)).toList(), - ),) - ); - } -} - -/// Renders a single comment given a comment model -class CommentItem extends StatelessWidget { - final Comment comment; - const CommentItem(this.comment); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.symmetric(vertical: 10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: commentColor), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - comment.name, - style: TextStyle(fontWeight: FontWeight.bold), - ), - UIHelper.verticalSpaceSmall(), - Text(comment.body), - ], - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/core/enums/viewstate.dart'; +import 'package:provider_architecutre/core/models/comment.dart'; +import 'package:provider_architecutre/core/viewmodels/comments_model.dart'; +import 'package:provider_architecutre/ui/shared/app_colors.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; +import 'package:provider_architecutre/ui/views/base_view.dart'; + +class Comments extends StatelessWidget { + final int postId; + Comments(this.postId); + + @override + Widget build(BuildContext context) { + return BaseView( + onModelReady: (model) => model.fetchComments(postId), + builder: (context, model, child) => model.state == ViewState.Busy + ? Center(child: CircularProgressIndicator()) + : Expanded(child: ListView( + children: model.comments + .map((comment) => CommentItem(comment)).toList(), + ),) + ); + } +} + +/// Renders a single comment given a comment model +class CommentItem extends StatelessWidget { + final Comment comment; + const CommentItem(this.comment); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.all(10.0), + margin: EdgeInsets.symmetric(vertical: 10.0), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), color: commentColor), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + comment.name, + style: TextStyle(fontWeight: FontWeight.bold), + ), + UIHelper.verticalSpaceSmall(), + Text(comment.body), + ], + ), + ); + } +} diff --git a/010-provider-architecture/002-final/lib/ui/widgets/login_header.dart b/010-provider-architecture/002-final/lib/ui/widgets/login_header.dart index a4bf50ad..394081d1 100644 --- a/010-provider-architecture/002-final/lib/ui/widgets/login_header.dart +++ b/010-provider-architecture/002-final/lib/ui/widgets/login_header.dart @@ -1,44 +1,44 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/ui/shared/text_styles.dart'; -import 'package:provider_architecture/ui/shared/ui_helpers.dart'; - -class LoginHeader extends StatelessWidget { - final TextEditingController controller; - final String validationMessage; - - LoginHeader({@required this.controller, this.validationMessage}); - - @override - Widget build(BuildContext context) { - return Column(children: [ - Text('Login', style: headerStyle), - UIHelper.verticalSpaceMedium(), - Text('Enter a number between 1 - 10', style: subHeaderStyle), - LoginTextField(controller), - this.validationMessage != null - ? Text(validationMessage, style: TextStyle(color: Colors.red)) - : Container() - ]); - } -} - -class LoginTextField extends StatelessWidget { - final TextEditingController controller; - - LoginTextField(this.controller); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 15.0), - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), - height: 50.0, - alignment: Alignment.centerLeft, - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - child: TextField( - decoration: InputDecoration.collapsed(hintText: 'User Id'), - controller: controller), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/ui/shared/text_styles.dart'; +import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; + +class LoginHeader extends StatelessWidget { + final TextEditingController controller; + final String validationMessage; + + LoginHeader({@required this.controller, this.validationMessage}); + + @override + Widget build(BuildContext context) { + return Column(children: [ + Text('Login', style: headerStyle), + UIHelper.verticalSpaceMedium(), + Text('Enter a number between 1 - 10', style: subHeaderStyle), + LoginTextField(controller), + this.validationMessage != null + ? Text(validationMessage, style: TextStyle(color: Colors.red)) + : Container() + ]); + } +} + +class LoginTextField extends StatelessWidget { + final TextEditingController controller; + + LoginTextField(this.controller); + + @override + Widget build(BuildContext context) { + return Container( + padding: EdgeInsets.symmetric(horizontal: 15.0), + margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), + height: 50.0, + alignment: Alignment.centerLeft, + decoration: BoxDecoration( + color: Colors.white, borderRadius: BorderRadius.circular(10.0)), + child: TextField( + decoration: InputDecoration.collapsed(hintText: 'User Id'), + controller: controller), + ); + } +} diff --git a/010-provider-architecture/002-final/lib/ui/widgets/postlist_item.dart b/010-provider-architecture/002-final/lib/ui/widgets/postlist_item.dart index ff6e04dd..d216cf3a 100644 --- a/010-provider-architecture/002-final/lib/ui/widgets/postlist_item.dart +++ b/010-provider-architecture/002-final/lib/ui/widgets/postlist_item.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecture/core/models/post.dart'; - -class PostListItem extends StatelessWidget { - final Post post; - final Function onTap; - const PostListItem({this.post, this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.0), - boxShadow: [ - BoxShadow( - blurRadius: 3.0, - offset: Offset(0.0, 2.0), - color: Color.fromARGB(80, 0, 0, 0)) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(post.title, style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0),), - Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) - ], - ), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:provider_architecutre/core/models/post.dart'; + +class PostListItem extends StatelessWidget { + final Post post; + final Function onTap; + const PostListItem({this.post, this.onTap}); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), + padding: EdgeInsets.all(10.0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(5.0), + boxShadow: [ + BoxShadow( + blurRadius: 3.0, + offset: Offset(0.0, 2.0), + color: Color.fromARGB(80, 0, 0, 0)) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(post.title, style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0),), + Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) + ], + ), + ), + ); + } +} diff --git a/010-provider-architecture/002-final/pubspec.lock b/010-provider-architecture/002-final/pubspec.lock index 5a814607..05b5b744 100644 --- a/010-provider-architecture/002-final/pubspec.lock +++ b/010-provider-architecture/002-final/pubspec.lock @@ -1,189 +1,174 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" +# Generated by pub +# See https://www.dartlang.org/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + get_it: + dependency: "direct main" + description: + name: get_it + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.0+2" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.3" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + provider: + dependency: "direct main" + description: + name: provider + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.5" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" +sdks: + dart: ">2.2.2 <3.0.0" diff --git a/010-provider-architecture/002-final/pubspec.yaml b/010-provider-architecture/002-final/pubspec.yaml index b6696620..2dd4fa46 100644 --- a/010-provider-architecture/002-final/pubspec.yaml +++ b/010-provider-architecture/002-final/pubspec.yaml @@ -1,23 +1,75 @@ -name: provider_architecture -description: A new Flutter project. - -version: 1.0.0+1 - -environment: - sdk: ">2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - get_it: ^4.0.2 - http: ^0.12.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -flutter: - uses-material-design: true +name: provider_architecutre +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">2.2.2 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + provider: ^2.0.1 + get_it: + http: ^0.12.0+2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/010-provider-architecture/002-final/test/widget_test.dart b/010-provider-architecture/002-final/test/widget_test.dart index 00be119e..bcf5bc8d 100644 --- a/010-provider-architecture/002-final/test/widget_test.dart +++ b/010-provider-architecture/002-final/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:provider_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:provider_architecutre/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/011-network-sensitive-ui/1-start/.gitignore b/011-network-sensitive-ui/1-start/.gitignore index aa35107b..ac4a9064 100644 --- a/011-network-sensitive-ui/1-start/.gitignore +++ b/011-network-sensitive-ui/1-start/.gitignore @@ -1,72 +1,72 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/011-network-sensitive-ui/1-start/.metadata b/011-network-sensitive-ui/1-start/.metadata index 11efa8a6..b78bb1fb 100644 --- a/011-network-sensitive-ui/1-start/.metadata +++ b/011-network-sensitive-ui/1-start/.metadata @@ -1,10 +1,10 @@ -# 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: 0578fe1d77b5767e2c08e7afddea73a465a35dc1 - channel: master - -project_type: app +# 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: 0578fe1d77b5767e2c08e7afddea73a465a35dc1 + channel: master + +project_type: app diff --git a/011-network-sensitive-ui/1-start/README.md b/011-network-sensitive-ui/1-start/README.md index d1dbefb6..29165c5f 100644 --- a/011-network-sensitive-ui/1-start/README.md +++ b/011-network-sensitive-ui/1-start/README.md @@ -1,3 +1,3 @@ -# Netowrk Aware UI - +# Netowrk Aware UI + This is the final resultfor [this tutorial](https://youtu.be/u9O8NOnQi_A) on Network Aware widgets in Flutter. \ No newline at end of file diff --git a/011-network-sensitive-ui/1-start/android/app/build.gradle b/011-network-sensitive-ui/1-start/android/app/build.gradle new file mode 100644 index 00000000..e2c71970 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.network_aware" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/011-network-sensitive-ui/1-start/android/app/src/debug/AndroidManifest.xml b/011-network-sensitive-ui/1-start/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..0132ce1f --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/AndroidManifest.xml b/011-network-sensitive-ui/1-start/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..5c72f431 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/java/com/example/network_aware/MainActivity.java b/011-network-sensitive-ui/1-start/android/app/src/main/java/com/example/network_aware/MainActivity.java new file mode 100644 index 00000000..6fa884e0 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/app/src/main/java/com/example/network_aware/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.network_aware; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/res/drawable/launch_background.xml b/011-network-sensitive-ui/1-start/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/011-network-sensitive-ui/1-start/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/1-start/android/app/src/main/res/values/styles.xml b/011-network-sensitive-ui/1-start/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/011-network-sensitive-ui/1-start/android/app/src/profile/AndroidManifest.xml b/011-network-sensitive-ui/1-start/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..0132ce1f --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/011-network-sensitive-ui/1-start/android/build.gradle b/011-network-sensitive-ui/1-start/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/011-network-sensitive-ui/1-start/android/gradle.properties b/011-network-sensitive-ui/1-start/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/011-network-sensitive-ui/1-start/android/gradle/wrapper/gradle-wrapper.properties b/011-network-sensitive-ui/1-start/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/011-network-sensitive-ui/1-start/android/settings.gradle b/011-network-sensitive-ui/1-start/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/011-network-sensitive-ui/1-start/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/011-network-sensitive-ui/1-start/ios/Flutter/AppFrameworkInfo.plist b/011-network-sensitive-ui/1-start/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/011-network-sensitive-ui/1-start/ios/Flutter/Debug.xcconfig b/011-network-sensitive-ui/1-start/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/011-network-sensitive-ui/1-start/ios/Flutter/Release.xcconfig b/011-network-sensitive-ui/1-start/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/project.pbxproj b/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..1b1e591c --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.networkAware; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.networkAware; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.networkAware; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/1-start/ios/Runner.xcworkspace/contents.xcworkspacedata b/011-network-sensitive-ui/1-start/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/011-network-sensitive-ui/1-start/ios/Runner/AppDelegate.h b/011-network-sensitive-ui/1-start/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/011-network-sensitive-ui/1-start/ios/Runner/AppDelegate.m b/011-network-sensitive-ui/1-start/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Base.lproj/LaunchScreen.storyboard b/011-network-sensitive-ui/1-start/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Base.lproj/Main.storyboard b/011-network-sensitive-ui/1-start/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/1-start/ios/Runner/Info.plist b/011-network-sensitive-ui/1-start/ios/Runner/Info.plist new file mode 100644 index 00000000..4c038a1c --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + network_aware + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/011-network-sensitive-ui/1-start/ios/Runner/main.m b/011-network-sensitive-ui/1-start/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/011-network-sensitive-ui/1-start/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/011-network-sensitive-ui/1-start/lib/main.dart b/011-network-sensitive-ui/1-start/lib/main.dart index 5ba676e9..f1015a89 100644 --- a/011-network-sensitive-ui/1-start/lib/main.dart +++ b/011-network-sensitive-ui/1-start/lib/main.dart @@ -1,19 +1,19 @@ -import 'package:flutter/material.dart'; -import 'package:network_aware/ui/home.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Connectivity Aware UI', - theme: ThemeData( - textTheme: Theme.of(context) - .textTheme - .apply(bodyColor: Colors.white, displayColor: Colors.white)), - home: HomeView(), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:network_aware/ui/home.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Connectivity Aware UI', + theme: ThemeData( + textTheme: Theme.of(context) + .textTheme + .apply(bodyColor: Colors.white, displayColor: Colors.white)), + home: HomeView(), + ); + } +} diff --git a/011-network-sensitive-ui/1-start/lib/ui/home.dart b/011-network-sensitive-ui/1-start/lib/ui/home.dart index b5cf5614..608c8306 100644 --- a/011-network-sensitive-ui/1-start/lib/ui/home.dart +++ b/011-network-sensitive-ui/1-start/lib/ui/home.dart @@ -1,71 +1,71 @@ -import 'package:flutter/material.dart'; -import 'package:network_aware/ui/shared/app_colors.dart'; -import 'package:network_aware/ui/widgets/stats_counter.dart'; -import 'package:network_aware/ui/widgets/watcher_toolbar.dart'; - -double screenHeight(BuildContext context, - {int dividedBy = 1, double decreasedBy = 0.0}) { - assert(dividedBy != 0, "Don't divide by 0"); - return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; -} - -class HomeView extends StatelessWidget { - static const int CounterMargins = 60; - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Column(children: [ - WatcherToolbar(title: 'SKELETON-WATCHER'), - _getHeightContainer( - context: context, - height: - screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), - child: StatsCounter( - size: screenHeight(context, - dividedBy: 2, decreasedBy: toolbarHeight) - - CounterMargins, // 60 margins - count: 13, - title: 'Errors', - titleColor: Colors.red, - ), - ), - _getHeightContainer( - context: context, - height: screenHeight(context, - dividedBy: 3, decreasedBy: toolbarHeight), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - StatsCounter( - size: screenHeight(context, - dividedBy: 3, decreasedBy: toolbarHeight) - - CounterMargins, - count: 55, - title: 'Users', - ), - StatsCounter( - size: screenHeight(context, - dividedBy: 3, decreasedBy: toolbarHeight) - - CounterMargins, - count: 2, - title: 'Apps Created', - ) - ])), - ])); - } - - Widget _getHeightContainer( - {double height, - BuildContext context, - Widget child, - bool hasTopStroke = false}) { - return Container( - height: height, - alignment: Alignment.center, - margin: EdgeInsets.symmetric(horizontal: 20.0), - child: child); - } -} +import 'package:flutter/material.dart'; +import 'package:network_aware/ui/shared/app_colors.dart'; +import 'package:network_aware/ui/widgets/stats_counter.dart'; +import 'package:network_aware/ui/widgets/watcher_toolbar.dart'; + +double screenHeight(BuildContext context, + {int dividedBy = 1, double decreasedBy = 0.0}) { + assert(dividedBy != 0, "Don't divide by 0"); + return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; +} + +class HomeView extends StatelessWidget { + static const int CounterMargins = 60; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: backgroundColor, + body: Column(children: [ + WatcherToolbar(title: 'SKELETON-WATCHER'), + _getHeightContainer( + context: context, + height: + screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), + child: StatsCounter( + size: screenHeight(context, + dividedBy: 2, decreasedBy: toolbarHeight) - + CounterMargins, // 60 margins + count: 13, + title: 'Errors', + titleColor: Colors.red, + ), + ), + _getHeightContainer( + context: context, + height: screenHeight(context, + dividedBy: 3, decreasedBy: toolbarHeight), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + StatsCounter( + size: screenHeight(context, + dividedBy: 3, decreasedBy: toolbarHeight) - + CounterMargins, + count: 55, + title: 'Users', + ), + StatsCounter( + size: screenHeight(context, + dividedBy: 3, decreasedBy: toolbarHeight) - + CounterMargins, + count: 2, + title: 'Apps Created', + ) + ])), + ])); + } + + Widget _getHeightContainer( + {double height, + BuildContext context, + Widget child, + bool hasTopStroke = false}) { + return Container( + height: height, + alignment: Alignment.center, + margin: EdgeInsets.symmetric(horizontal: 20.0), + child: child); + } +} diff --git a/011-network-sensitive-ui/1-start/lib/ui/shared/app_colors.dart b/011-network-sensitive-ui/1-start/lib/ui/shared/app_colors.dart index e5ca3a2c..d976c11e 100644 --- a/011-network-sensitive-ui/1-start/lib/ui/shared/app_colors.dart +++ b/011-network-sensitive-ui/1-start/lib/ui/shared/app_colors.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); +import 'package:flutter/material.dart'; + +const Color lightGrey = Color.fromARGB(255,61,63,69); +const Color darkGrey = Color.fromARGB(255,18,18,19); +const Color primaryColor = Color.fromARGB(255, 9, 202, 172); +const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/011-network-sensitive-ui/1-start/lib/ui/widgets/stats_counter.dart b/011-network-sensitive-ui/1-start/lib/ui/widgets/stats_counter.dart index 98d5d659..1748192a 100644 --- a/011-network-sensitive-ui/1-start/lib/ui/widgets/stats_counter.dart +++ b/011-network-sensitive-ui/1-start/lib/ui/widgets/stats_counter.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import '../shared/app_colors.dart'; - -class StatsCounter extends StatelessWidget { - final double size; - final int count; - final String title; - final Color titleColor; - - StatsCounter( - {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); - - @override - Widget build(BuildContext context) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: darkGrey), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text(count.toString(), - textAlign: TextAlign.center, - style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), - Text(title, - textAlign: TextAlign.center, - style: TextStyle( - color: titleColor, - fontSize: size * 0.1, fontWeight: FontWeight.w400)) - ]), - ); - } -} +import 'package:flutter/material.dart'; +import '../shared/app_colors.dart'; + +class StatsCounter extends StatelessWidget { + final double size; + final int count; + final String title; + final Color titleColor; + + StatsCounter( + {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); + + @override + Widget build(BuildContext context) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: darkGrey), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(count.toString(), + textAlign: TextAlign.center, + style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), + Text(title, + textAlign: TextAlign.center, + style: TextStyle( + color: titleColor, + fontSize: size * 0.1, fontWeight: FontWeight.w400)) + ]), + ); + } +} diff --git a/011-network-sensitive-ui/1-start/lib/ui/widgets/watcher_toolbar.dart b/011-network-sensitive-ui/1-start/lib/ui/widgets/watcher_toolbar.dart index afaf138d..8161765e 100644 --- a/011-network-sensitive-ui/1-start/lib/ui/widgets/watcher_toolbar.dart +++ b/011-network-sensitive-ui/1-start/lib/ui/widgets/watcher_toolbar.dart @@ -1,38 +1,38 @@ -import 'package:flutter/material.dart'; - -const double toolbarHeight = 80.0; - -class WatcherToolbar extends StatelessWidget { - final String title; - final bool showBackButton; - const WatcherToolbar({@required this.title, this.showBackButton = false}); - - @override - Widget build(BuildContext context) { - return Container( - height: toolbarHeight, - margin: EdgeInsets.symmetric(horizontal: 20.0), - child: Row( - children: [ - showBackButton - ? GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.centerLeft, - width: 50, - child: Icon(Icons.chevron_left, - size: 30, color: Colors.white)), - ) - : Container(), - Expanded( - child: Text(title, - textAlign: TextAlign.right, - style: TextStyle(fontWeight: FontWeight.w800)), - ), - ], - ), - ); - } +import 'package:flutter/material.dart'; + +const double toolbarHeight = 80.0; + +class WatcherToolbar extends StatelessWidget { + final String title; + final bool showBackButton; + const WatcherToolbar({@required this.title, this.showBackButton = false}); + + @override + Widget build(BuildContext context) { + return Container( + height: toolbarHeight, + margin: EdgeInsets.symmetric(horizontal: 20.0), + child: Row( + children: [ + showBackButton + ? GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Container( + alignment: Alignment.centerLeft, + width: 50, + child: Icon(Icons.chevron_left, + size: 30, color: Colors.white)), + ) + : Container(), + Expanded( + child: Text(title, + textAlign: TextAlign.right, + style: TextStyle(fontWeight: FontWeight.w800)), + ), + ], + ), + ); + } } \ No newline at end of file diff --git a/011-network-sensitive-ui/1-start/pubspec.lock b/011-network-sensitive-ui/1-start/pubspec.lock index 2e161248..00332f26 100644 --- a/011-network-sensitive-ui/1-start/pubspec.lock +++ b/011-network-sensitive-ui/1-start/pubspec.lock @@ -1,146 +1,146 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" +# Generated by pub +# See https://www.dartlang.org/tools/pub/glossary#lockfile +packages: + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.5" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.2" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.5" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.5" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" +sdks: + dart: ">=2.2.0 <3.0.0" diff --git a/011-network-sensitive-ui/1-start/pubspec.yaml b/011-network-sensitive-ui/1-start/pubspec.yaml index 3c5ab4bf..310fdd37 100644 --- a/011-network-sensitive-ui/1-start/pubspec.yaml +++ b/011-network-sensitive-ui/1-start/pubspec.yaml @@ -1,66 +1,72 @@ -name: network_aware -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: network_aware +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/011-network-sensitive-ui/1-start/test/widget_test.dart b/011-network-sensitive-ui/1-start/test/widget_test.dart index 5fe7f42e..dcdad32a 100644 --- a/011-network-sensitive-ui/1-start/test/widget_test.dart +++ b/011-network-sensitive-ui/1-start/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:network_aware/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:network_aware/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/011-network-sensitive-ui/2-final/.flutter-plugins-dependencies b/011-network-sensitive-ui/2-final/.flutter-plugins-dependencies deleted file mode 100644 index 3b9a090d..00000000 --- a/011-network-sensitive-ui/2-final/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/connectivity-0.4.8+6/","dependencies":[]}],"android":[{"name":"connectivity","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/connectivity-0.4.8+6/","dependencies":[]}],"macos":[{"name":"connectivity_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/connectivity_macos-0.1.0+3/","dependencies":[]}],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"connectivity","dependencies":["connectivity_macos"]},{"name":"connectivity_macos","dependencies":[]}],"date_created":"2020-06-18 21:50:13.415706","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/011-network-sensitive-ui/2-final/.gitignore b/011-network-sensitive-ui/2-final/.gitignore index aa35107b..ac4a9064 100644 --- a/011-network-sensitive-ui/2-final/.gitignore +++ b/011-network-sensitive-ui/2-final/.gitignore @@ -1,72 +1,72 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +/build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/011-network-sensitive-ui/2-final/.metadata b/011-network-sensitive-ui/2-final/.metadata index 11efa8a6..b78bb1fb 100644 --- a/011-network-sensitive-ui/2-final/.metadata +++ b/011-network-sensitive-ui/2-final/.metadata @@ -1,10 +1,10 @@ -# 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: 0578fe1d77b5767e2c08e7afddea73a465a35dc1 - channel: master - -project_type: app +# 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: 0578fe1d77b5767e2c08e7afddea73a465a35dc1 + channel: master + +project_type: app diff --git a/011-network-sensitive-ui/2-final/README.md b/011-network-sensitive-ui/2-final/README.md index d37cc59e..6f4cdc36 100644 --- a/011-network-sensitive-ui/2-final/README.md +++ b/011-network-sensitive-ui/2-final/README.md @@ -1,3 +1,3 @@ -# Netowrk Aware UI - +# Netowrk Aware UI + This is the starting project for [this tutorial](https://youtu.be/u9O8NOnQi_A) on Network Aware widgets in Flutter. \ No newline at end of file diff --git a/011-network-sensitive-ui/2-final/android/app/build.gradle b/011-network-sensitive-ui/2-final/android/app/build.gradle new file mode 100644 index 00000000..e2c71970 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 28 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.network_aware" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/011-network-sensitive-ui/2-final/android/app/src/debug/AndroidManifest.xml b/011-network-sensitive-ui/2-final/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..0132ce1f --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/AndroidManifest.xml b/011-network-sensitive-ui/2-final/android/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..5c72f431 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/java/com/example/network_aware/MainActivity.java b/011-network-sensitive-ui/2-final/android/app/src/main/java/com/example/network_aware/MainActivity.java new file mode 100644 index 00000000..6fa884e0 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/app/src/main/java/com/example/network_aware/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.network_aware; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/res/drawable/launch_background.xml b/011-network-sensitive-ui/2-final/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 00000000..304732f8 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 00000000..db77bb4b Binary files /dev/null and b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 00000000..17987b79 Binary files /dev/null and b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 00000000..09d43914 Binary files /dev/null and b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 00000000..d5f1c8d3 Binary files /dev/null and b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 00000000..4d6372ee Binary files /dev/null and b/011-network-sensitive-ui/2-final/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/011-network-sensitive-ui/2-final/android/app/src/main/res/values/styles.xml b/011-network-sensitive-ui/2-final/android/app/src/main/res/values/styles.xml new file mode 100644 index 00000000..00fa4417 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/011-network-sensitive-ui/2-final/android/app/src/profile/AndroidManifest.xml b/011-network-sensitive-ui/2-final/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 00000000..0132ce1f --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/011-network-sensitive-ui/2-final/android/build.gradle b/011-network-sensitive-ui/2-final/android/build.gradle new file mode 100644 index 00000000..bb8a3038 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.2.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/011-network-sensitive-ui/2-final/android/gradle.properties b/011-network-sensitive-ui/2-final/android/gradle.properties new file mode 100644 index 00000000..8bd86f68 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/011-network-sensitive-ui/2-final/android/gradle/wrapper/gradle-wrapper.properties b/011-network-sensitive-ui/2-final/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 00000000..2819f022 --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip diff --git a/011-network-sensitive-ui/2-final/android/settings.gradle b/011-network-sensitive-ui/2-final/android/settings.gradle new file mode 100644 index 00000000..5a2f14fb --- /dev/null +++ b/011-network-sensitive-ui/2-final/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/011-network-sensitive-ui/2-final/ios/Flutter/AppFrameworkInfo.plist b/011-network-sensitive-ui/2-final/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 00000000..9367d483 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/011-network-sensitive-ui/2-final/ios/Flutter/Debug.xcconfig b/011-network-sensitive-ui/2-final/ios/Flutter/Debug.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/011-network-sensitive-ui/2-final/ios/Flutter/Release.xcconfig b/011-network-sensitive-ui/2-final/ios/Flutter/Release.xcconfig new file mode 100644 index 00000000..592ceee8 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/project.pbxproj b/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 00000000..1b1e591c --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,506 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 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 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + 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 = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + 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"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = 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; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = S8QB4VV633; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.networkAware; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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_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_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; + 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 = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.networkAware; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.networkAware; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 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 */; +} diff --git a/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 00000000..786d6aad --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/2-final/ios/Runner.xcworkspace/contents.xcworkspacedata b/011-network-sensitive-ui/2-final/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..1d526a16 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/011-network-sensitive-ui/2-final/ios/Runner/AppDelegate.h b/011-network-sensitive-ui/2-final/ios/Runner/AppDelegate.h new file mode 100644 index 00000000..36e21bbf --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/011-network-sensitive-ui/2-final/ios/Runner/AppDelegate.m b/011-network-sensitive-ui/2-final/ios/Runner/AppDelegate.m new file mode 100644 index 00000000..59a72e90 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..d36b1fab --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "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" + } +} diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 00000000..3d43d11e Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 00000000..28c6bf03 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 00000000..f091b6b0 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 00000000..4cde1211 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 00000000..d0ef06e7 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 00000000..dcdc2306 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 00000000..2ccbfd96 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 00000000..c8f9ed8f Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 00000000..a6d6b860 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 00000000..75b2d164 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 00000000..c4df70d3 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 00000000..6a84f41e Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 00000000..d0e1f585 Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 00000000..0bedcf2f --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "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" + } +} diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 00000000..9da19eac Binary files /dev/null and b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 00000000..89c2725b --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# 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. \ No newline at end of file diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Base.lproj/LaunchScreen.storyboard b/011-network-sensitive-ui/2-final/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 00000000..f2e259c7 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Base.lproj/Main.storyboard b/011-network-sensitive-ui/2-final/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 00000000..f3c28516 --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/011-network-sensitive-ui/2-final/ios/Runner/Info.plist b/011-network-sensitive-ui/2-final/ios/Runner/Info.plist new file mode 100644 index 00000000..4c038a1c --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + network_aware + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/011-network-sensitive-ui/2-final/ios/Runner/main.m b/011-network-sensitive-ui/2-final/ios/Runner/main.m new file mode 100644 index 00000000..dff6597e --- /dev/null +++ b/011-network-sensitive-ui/2-final/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/011-network-sensitive-ui/2-final/lib/enums/connectivity_status.dart b/011-network-sensitive-ui/2-final/lib/enums/connectivity_status.dart index 02583d15..aa025485 100644 --- a/011-network-sensitive-ui/2-final/lib/enums/connectivity_status.dart +++ b/011-network-sensitive-ui/2-final/lib/enums/connectivity_status.dart @@ -1,5 +1,5 @@ -enum ConnectivityStatus { - WiFi, - Cellular, - Offline +enum ConnectivityStatus { + WiFi, + Cellular, + Offline } \ No newline at end of file diff --git a/011-network-sensitive-ui/2-final/lib/main.dart b/011-network-sensitive-ui/2-final/lib/main.dart index 7acb9954..572a726c 100644 --- a/011-network-sensitive-ui/2-final/lib/main.dart +++ b/011-network-sensitive-ui/2-final/lib/main.dart @@ -1,27 +1,26 @@ -import 'package:flutter/material.dart'; -import 'package:network_aware/services/connectivity_service.dart'; -import 'package:network_aware/ui/home.dart'; -import 'package:provider/provider.dart'; - -import 'enums/connectivity_status.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return StreamProvider( - create: (context) => - ConnectivityService().connectionStatusController.stream, - child: MaterialApp( - title: 'Connectivity Aware UI', - theme: ThemeData( - textTheme: Theme.of(context) - .textTheme - .apply(bodyColor: Colors.white, displayColor: Colors.white)), - home: HomeView(), - ), - ); - } -} +import 'package:flutter/material.dart'; +import 'package:network_aware/services/connectivity_service.dart'; +import 'package:network_aware/ui/home.dart'; +import 'package:provider/provider.dart'; + +import 'enums/connectivity_status.dart'; + +void main() => runApp(MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return StreamProvider( + builder: (context) => ConnectivityService().connectionStatusController, + child: MaterialApp( + title: 'Connectivity Aware UI', + theme: ThemeData( + textTheme: Theme.of(context) + .textTheme + .apply(bodyColor: Colors.white, displayColor: Colors.white)), + home: HomeView(), + ), + ); + } +} diff --git a/011-network-sensitive-ui/2-final/lib/services/connectivity_service.dart b/011-network-sensitive-ui/2-final/lib/services/connectivity_service.dart index cfe1ed64..1b8eeab7 100644 --- a/011-network-sensitive-ui/2-final/lib/services/connectivity_service.dart +++ b/011-network-sensitive-ui/2-final/lib/services/connectivity_service.dart @@ -1,32 +1,32 @@ -import 'dart:async'; - -import 'package:connectivity/connectivity.dart'; -import 'package:network_aware/enums/connectivity_status.dart'; - -class ConnectivityService { - // Create our public controller - StreamController connectionStatusController = StreamController(); - - ConnectivityService() { - // Subscribe to the connectivity Chanaged Steam - Connectivity().onConnectivityChanged.listen((ConnectivityResult result) { - // Use Connectivity() here to gather more info if you need t - - connectionStatusController.add(_getStatusFromResult(result)); - }); - } - - // Convert from the third part enum to our own enum - ConnectivityStatus _getStatusFromResult(ConnectivityResult result) { - switch (result) { - case ConnectivityResult.mobile: - return ConnectivityStatus.Cellular; - case ConnectivityResult.wifi: - return ConnectivityStatus.WiFi; - case ConnectivityResult.none: - return ConnectivityStatus.Offline; - default: - return ConnectivityStatus.Offline; - } - } +import 'dart:async'; + +import 'package:connectivity/connectivity.dart'; +import 'package:network_aware/enums/connectivity_status.dart'; + +class ConnectivityService { + // Create our public controller + StreamController connectionStatusController = StreamController(); + + ConnectivityService() { + // Subscribe to the connectivity Chanaged Steam + Connectivity().onConnectivityChanged.listen((ConnectivityResult result) { + // Use Connectivity() here to gather more info if you need t + + connectionStatusController.add(_getStatusFromResult(result)); + }); + } + + // Convert from the third part enum to our own enum + ConnectivityStatus _getStatusFromResult(ConnectivityResult result) { + switch (result) { + case ConnectivityResult.mobile: + return ConnectivityStatus.Cellular; + case ConnectivityResult.wifi: + return ConnectivityStatus.WiFi; + case ConnectivityResult.none: + return ConnectivityStatus.Offline; + default: + return ConnectivityStatus.Offline; + } + } } \ No newline at end of file diff --git a/011-network-sensitive-ui/2-final/lib/ui/home.dart b/011-network-sensitive-ui/2-final/lib/ui/home.dart index b0e0fb72..54888d5a 100644 --- a/011-network-sensitive-ui/2-final/lib/ui/home.dart +++ b/011-network-sensitive-ui/2-final/lib/ui/home.dart @@ -1,76 +1,76 @@ -import 'package:flutter/material.dart'; -import 'package:network_aware/ui/shared/app_colors.dart'; -import 'package:network_aware/ui/widgets/network_sensitive.dart'; -import 'package:network_aware/ui/widgets/stats_counter.dart'; -import 'package:network_aware/ui/widgets/watcher_toolbar.dart'; - -double screenHeight(BuildContext context, - {int dividedBy = 1, double decreasedBy = 0.0}) { - assert(dividedBy != 0, "Don't divide by 0"); - return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; -} - -class HomeView extends StatelessWidget { - static const int CounterMargins = 60; - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Column(children: [ - WatcherToolbar(title: 'SKELETON-WATCHER'), - _getHeightContainer( - context: context, - height: - screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), - child: NetworkSensitive( - child: StatsCounter( - size: screenHeight(context, - dividedBy: 2, decreasedBy: toolbarHeight) - - CounterMargins, // 60 margins - count: 13, - title: 'Errors', - titleColor: Colors.red, - ), - ), - ), - _getHeightContainer( - context: context, - height: screenHeight(context, - dividedBy: 3, decreasedBy: toolbarHeight), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - NetworkSensitive( - child: StatsCounter( - size: screenHeight(context, - dividedBy: 3, decreasedBy: toolbarHeight) - - CounterMargins, - count: 55, - title: 'Users', - ), - ), - StatsCounter( - size: screenHeight(context, - dividedBy: 3, decreasedBy: toolbarHeight) - - CounterMargins, - count: 2, - title: 'Apps Created', - ) - ])), - ])); - } - - Widget _getHeightContainer( - {double height, - BuildContext context, - Widget child, - bool hasTopStroke = false}) { - return Container( - height: height, - alignment: Alignment.center, - margin: EdgeInsets.symmetric(horizontal: 20.0), - child: child); - } -} +import 'package:flutter/material.dart'; +import 'package:network_aware/ui/shared/app_colors.dart'; +import 'package:network_aware/ui/widgets/network_sensitive.dart'; +import 'package:network_aware/ui/widgets/stats_counter.dart'; +import 'package:network_aware/ui/widgets/watcher_toolbar.dart'; + +double screenHeight(BuildContext context, + {int dividedBy = 1, double decreasedBy = 0.0}) { + assert(dividedBy != 0, "Don't divide by 0"); + return (MediaQuery.of(context).size.height - decreasedBy) / dividedBy; +} + +class HomeView extends StatelessWidget { + static const int CounterMargins = 60; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: backgroundColor, + body: Column(children: [ + WatcherToolbar(title: 'SKELETON-WATCHER'), + _getHeightContainer( + context: context, + height: + screenHeight(context, dividedBy: 2, decreasedBy: toolbarHeight), + child: NetworkSensitive( + child: StatsCounter( + size: screenHeight(context, + dividedBy: 2, decreasedBy: toolbarHeight) - + CounterMargins, // 60 margins + count: 13, + title: 'Errors', + titleColor: Colors.red, + ), + ), + ), + _getHeightContainer( + context: context, + height: screenHeight(context, + dividedBy: 3, decreasedBy: toolbarHeight), + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + NetworkSensitive( + child: StatsCounter( + size: screenHeight(context, + dividedBy: 3, decreasedBy: toolbarHeight) - + CounterMargins, + count: 55, + title: 'Users', + ), + ), + StatsCounter( + size: screenHeight(context, + dividedBy: 3, decreasedBy: toolbarHeight) - + CounterMargins, + count: 2, + title: 'Apps Created', + ) + ])), + ])); + } + + Widget _getHeightContainer( + {double height, + BuildContext context, + Widget child, + bool hasTopStroke = false}) { + return Container( + height: height, + alignment: Alignment.center, + margin: EdgeInsets.symmetric(horizontal: 20.0), + child: child); + } +} diff --git a/011-network-sensitive-ui/2-final/lib/ui/shared/app_colors.dart b/011-network-sensitive-ui/2-final/lib/ui/shared/app_colors.dart index e5ca3a2c..d976c11e 100644 --- a/011-network-sensitive-ui/2-final/lib/ui/shared/app_colors.dart +++ b/011-network-sensitive-ui/2-final/lib/ui/shared/app_colors.dart @@ -1,6 +1,6 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); +import 'package:flutter/material.dart'; + +const Color lightGrey = Color.fromARGB(255,61,63,69); +const Color darkGrey = Color.fromARGB(255,18,18,19); +const Color primaryColor = Color.fromARGB(255, 9, 202, 172); +const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/011-network-sensitive-ui/2-final/lib/ui/widgets/network_sensitive.dart b/011-network-sensitive-ui/2-final/lib/ui/widgets/network_sensitive.dart index de8989e2..c33149b7 100644 --- a/011-network-sensitive-ui/2-final/lib/ui/widgets/network_sensitive.dart +++ b/011-network-sensitive-ui/2-final/lib/ui/widgets/network_sensitive.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import 'package:network_aware/enums/connectivity_status.dart'; -import 'package:provider/provider.dart'; - -class NetworkSensitive extends StatelessWidget { - final Widget child; - final double opacity; - - NetworkSensitive({ - this.child, - this.opacity = 0.5, - }); - - @override - Widget build(BuildContext context) { - // Get our connection status from the provider - var connectionStatus = Provider.of(context); - - if (connectionStatus == ConnectivityStatus.WiFi) { - return child; - } - - if (connectionStatus == ConnectivityStatus.Cellular) { - return Opacity( - opacity: opacity, - child: child, - ); - } - - return Opacity( - opacity: 0.1, - child: child, - ); - } -} +import 'package:flutter/material.dart'; +import 'package:network_aware/enums/connectivity_status.dart'; +import 'package:provider/provider.dart'; + +class NetworkSensitive extends StatelessWidget { + final Widget child; + final double opacity; + + NetworkSensitive({ + this.child, + this.opacity = 0.5, + }); + + @override + Widget build(BuildContext context) { + // Get our connection status from the provider + var connectionStatus = Provider.of(context); + + if (connectionStatus == ConnectivityStatus.WiFi) { + return child; + } + + if (connectionStatus == ConnectivityStatus.Cellular) { + return Opacity( + opacity: opacity, + child: child, + ); + } + + return Opacity( + opacity: 0.1, + child: child, + ); + } +} diff --git a/011-network-sensitive-ui/2-final/lib/ui/widgets/stats_counter.dart b/011-network-sensitive-ui/2-final/lib/ui/widgets/stats_counter.dart index 98d5d659..1748192a 100644 --- a/011-network-sensitive-ui/2-final/lib/ui/widgets/stats_counter.dart +++ b/011-network-sensitive-ui/2-final/lib/ui/widgets/stats_counter.dart @@ -1,35 +1,35 @@ -import 'package:flutter/material.dart'; -import '../shared/app_colors.dart'; - -class StatsCounter extends StatelessWidget { - final double size; - final int count; - final String title; - final Color titleColor; - - StatsCounter( - {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); - - @override - Widget build(BuildContext context) { - return Container( - width: size, - height: size, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5.0), color: darkGrey), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Text(count.toString(), - textAlign: TextAlign.center, - style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), - Text(title, - textAlign: TextAlign.center, - style: TextStyle( - color: titleColor, - fontSize: size * 0.1, fontWeight: FontWeight.w400)) - ]), - ); - } -} +import 'package:flutter/material.dart'; +import '../shared/app_colors.dart'; + +class StatsCounter extends StatelessWidget { + final double size; + final int count; + final String title; + final Color titleColor; + + StatsCounter( + {@required this.size, @required this.count, @required this.title, this.titleColor = Colors.white}); + + @override + Widget build(BuildContext context) { + return Container( + width: size, + height: size, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5.0), color: darkGrey), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(count.toString(), + textAlign: TextAlign.center, + style: TextStyle(fontSize: size *0.6, fontWeight: FontWeight.w800)), + Text(title, + textAlign: TextAlign.center, + style: TextStyle( + color: titleColor, + fontSize: size * 0.1, fontWeight: FontWeight.w400)) + ]), + ); + } +} diff --git a/011-network-sensitive-ui/2-final/lib/ui/widgets/watcher_toolbar.dart b/011-network-sensitive-ui/2-final/lib/ui/widgets/watcher_toolbar.dart index afaf138d..8161765e 100644 --- a/011-network-sensitive-ui/2-final/lib/ui/widgets/watcher_toolbar.dart +++ b/011-network-sensitive-ui/2-final/lib/ui/widgets/watcher_toolbar.dart @@ -1,38 +1,38 @@ -import 'package:flutter/material.dart'; - -const double toolbarHeight = 80.0; - -class WatcherToolbar extends StatelessWidget { - final String title; - final bool showBackButton; - const WatcherToolbar({@required this.title, this.showBackButton = false}); - - @override - Widget build(BuildContext context) { - return Container( - height: toolbarHeight, - margin: EdgeInsets.symmetric(horizontal: 20.0), - child: Row( - children: [ - showBackButton - ? GestureDetector( - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.centerLeft, - width: 50, - child: Icon(Icons.chevron_left, - size: 30, color: Colors.white)), - ) - : Container(), - Expanded( - child: Text(title, - textAlign: TextAlign.right, - style: TextStyle(fontWeight: FontWeight.w800)), - ), - ], - ), - ); - } +import 'package:flutter/material.dart'; + +const double toolbarHeight = 80.0; + +class WatcherToolbar extends StatelessWidget { + final String title; + final bool showBackButton; + const WatcherToolbar({@required this.title, this.showBackButton = false}); + + @override + Widget build(BuildContext context) { + return Container( + height: toolbarHeight, + margin: EdgeInsets.symmetric(horizontal: 20.0), + child: Row( + children: [ + showBackButton + ? GestureDetector( + onTap: () { + Navigator.pop(context); + }, + child: Container( + alignment: Alignment.centerLeft, + width: 50, + child: Icon(Icons.chevron_left, + size: 30, color: Colors.white)), + ) + : Container(), + Expanded( + child: Text(title, + textAlign: TextAlign.right, + style: TextStyle(fontWeight: FontWeight.w800)), + ), + ], + ), + ); + } } \ No newline at end of file diff --git a/011-network-sensitive-ui/2-final/pubspec.lock b/011-network-sensitive-ui/2-final/pubspec.lock index ff72d561..76f1cb6d 100644 --- a/011-network-sensitive-ui/2-final/pubspec.lock +++ b/011-network-sensitive-ui/2-final/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile +# See https://www.dartlang.org/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,70 +7,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.2.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.14.11" connectivity: dependency: "direct main" description: name: connectivity url: "https://pub.dartlang.org" source: hosted - version: "0.4.8+6" - connectivity_macos: - dependency: transitive - description: - name: connectivity_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.0+3" - connectivity_platform_interface: - dependency: transitive - description: - name: connectivity_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.6" + version: "0.4.3+1" cupertino_icons: dependency: "direct main" description: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -87,42 +59,42 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.5" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" + version: "1.1.6" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" - plugin_platform_interface: + version: "1.6.2" + pedantic: dependency: transitive description: - name: plugin_platform_interface + name: pedantic url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.5.0" provider: dependency: "direct main" description: name: provider url: "https://pub.dartlang.org" source: hosted - version: "4.1.3" + version: "2.0.1" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.3" sky_engine: dependency: transitive description: flutter @@ -134,7 +106,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.5.5" stack_trace: dependency: transitive description: @@ -155,7 +127,7 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.4" term_glyph: dependency: transitive description: @@ -169,7 +141,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.5" typed_data: dependency: transitive description: @@ -185,5 +157,5 @@ packages: source: hosted version: "2.0.8" sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" + dart: ">=2.2.0 <3.0.0" + flutter: ">=1.2.0 <2.0.0" diff --git a/011-network-sensitive-ui/2-final/pubspec.yaml b/011-network-sensitive-ui/2-final/pubspec.yaml index f76826e9..4d332ade 100644 --- a/011-network-sensitive-ui/2-final/pubspec.yaml +++ b/011-network-sensitive-ui/2-final/pubspec.yaml @@ -1,68 +1,74 @@ -name: network_aware -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - connectivity: ^0.4.8+6 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages +name: network_aware +description: A new Flutter project. + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.2 + connectivity: ^0.4.3+1 + provider: ^2.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/011-network-sensitive-ui/2-final/test/widget_test.dart b/011-network-sensitive-ui/2-final/test/widget_test.dart index 5fe7f42e..dcdad32a 100644 --- a/011-network-sensitive-ui/2-final/test/widget_test.dart +++ b/011-network-sensitive-ui/2-final/test/widget_test.dart @@ -1,30 +1,30 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:network_aware/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:network_aware/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} diff --git a/012-provider-architecture-pt2/1-start/.gitignore b/012-provider-architecture-pt2/1-start/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/012-provider-architecture-pt2/1-start/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/012-provider-architecture-pt2/1-start/.metadata b/012-provider-architecture-pt2/1-start/.metadata deleted file mode 100644 index b9fdc6b5..00000000 --- a/012-provider-architecture-pt2/1-start/.metadata +++ /dev/null @@ -1,10 +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: fbe11671a4b78a707d9856588d956c0d3c39a6d5 - channel: master - -project_type: app diff --git a/012-provider-architecture-pt2/1-start/README.md b/012-provider-architecture-pt2/1-start/README.md deleted file mode 100644 index 2d408426..00000000 --- a/012-provider-architecture-pt2/1-start/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Provider + Get_it Architecture - -This is the final result of [this tutorial](https://www.filledstacks.com/post/flutter-architecture-my-provider-implementation-guide) where we setup a Flutter app architecture using the Provider package. \ No newline at end of file diff --git a/012-provider-architecture-pt2/1-start/lib/core/models/comment.dart b/012-provider-architecture-pt2/1-start/lib/core/models/comment.dart deleted file mode 100644 index 6a2ebec8..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/models/comment.dart +++ /dev/null @@ -1,27 +0,0 @@ -class Comment { - int postId; - int id; - String name; - String email; - String body; - - Comment({this.postId, this.id, this.name, this.email, this.body}); - - Comment.fromJson(Map json) { - postId = json['postId']; - id = json['id']; - name = json['name']; - email = json['email']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['postId'] = this.postId; - data['id'] = this.id; - data['name'] = this.name; - data['email'] = this.email; - data['body'] = this.body; - return data; - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/1-start/lib/core/models/post.dart b/012-provider-architecture-pt2/1-start/lib/core/models/post.dart deleted file mode 100644 index c1c6cf92..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/models/post.dart +++ /dev/null @@ -1,24 +0,0 @@ -class Post { - int userId; - int id; - String title; - String body; - - Post({this.userId, this.id, this.title, this.body}); - - Post.fromJson(Map json) { - userId = json['userId']; - id = json['id']; - title = json['title']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['id'] = this.id; - data['title'] = this.title; - data['body'] = this.body; - return data; - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/1-start/lib/core/models/user.dart b/012-provider-architecture-pt2/1-start/lib/core/models/user.dart deleted file mode 100644 index 1071dc6c..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/models/user.dart +++ /dev/null @@ -1,25 +0,0 @@ -class User { - int id; - String name; - String username; - User({this.id, this.name, this.username}); - - User.initial() - : id = 0, - name = '', - username = ''; - - User.fromJson(Map json) { - id = json['id']; - name = json['name']; - username = json['username']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['username'] = this.username; - return data; - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/core/services/api.dart b/012-provider-architecture-pt2/1-start/lib/core/services/api.dart deleted file mode 100644 index f763c49b..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/services/api.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:convert'; - -import 'package:provider_architecutre/core/models/comment.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/models/user.dart'; -import 'package:http/http.dart' as http; - -/// The service responsible for networking requests -class Api { - static const endpoint = 'https://jsonplaceholder.typicode.com'; - - var client = new http.Client(); - - Future getUserProfile(int userId) async { - // Get user profile for id - var response = await client.get('$endpoint/users/$userId'); - - // Convert and return - return User.fromJson(json.decode(response.body)); - } - - Future> getPostsForUser(int userId) async { - var posts = List(); - // Get user posts for id - var response = await client.get('$endpoint/posts?userId=$userId'); - - // parse into List - var parsed = json.decode(response.body) as List; - - // loop and convert each item to Post - for (var post in parsed) { - posts.add(Post.fromJson(post)); - } - - return posts; - } - - Future> getCommentsForPost(int postId) async { - var comments = List(); - - // Get comments for post - var response = await client.get('$endpoint/comments?postId=$postId'); - - // Parse into List - var parsed = json.decode(response.body) as List; - - // Loop and convert each item to a Comment - for (var comment in parsed) { - comments.add(Comment.fromJson(comment)); - } - - return comments; - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/core/services/authentication_service.dart b/012-provider-architecture-pt2/1-start/lib/core/services/authentication_service.dart deleted file mode 100644 index 90c322cb..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/services/authentication_service.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'dart:async'; - -import 'package:provider_architecutre/core/models/user.dart'; - -import '../../locator.dart'; -import 'api.dart'; - -class AuthenticationService { - Api _api = locator(); - - StreamController userController = StreamController(); - - Future login(int userId) async { - var fetchedUser = await _api.getUserProfile(userId); - - var hasUser = fetchedUser != null; - if(hasUser) { - userController.add(fetchedUser); - } - - return hasUser; - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/base_model.dart b/012-provider-architecture-pt2/1-start/lib/core/viewmodels/base_model.dart deleted file mode 100644 index 4da436d2..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/base_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; - -class BaseModel extends ChangeNotifier { - ViewState _state = ViewState.Idle; - - ViewState get state => _state; - - void setState(ViewState viewState) { - _state = viewState; - notifyListeners(); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/comments_model.dart b/012-provider-architecture-pt2/1-start/lib/core/viewmodels/comments_model.dart deleted file mode 100644 index 77cb8de4..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/comments_model.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/comment.dart'; -import 'package:provider_architecutre/core/services/api.dart'; - -import '../../locator.dart'; -import 'base_model.dart'; - -class CommentsModel extends BaseModel { - Api _api = locator(); - - List comments; - - Future fetchComments(int postId) async { - setState(ViewState.Busy); - comments = await _api.getCommentsForPost(postId); - setState(ViewState.Idle); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/home_model.dart b/012-provider-architecture-pt2/1-start/lib/core/viewmodels/home_model.dart deleted file mode 100644 index eb366f07..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/home_model.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/services/api.dart'; -import 'package:provider_architecutre/locator.dart'; - -import 'base_model.dart'; - -class HomeModel extends BaseModel { - Api _api = locator(); - - List posts; - - Future getPosts(int userId) async { - setState(ViewState.Busy); - posts = await _api.getPostsForUser(userId); - setState(ViewState.Idle); - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/login_model.dart b/012-provider-architecture-pt2/1-start/lib/core/viewmodels/login_model.dart deleted file mode 100644 index e690c2e3..00000000 --- a/012-provider-architecture-pt2/1-start/lib/core/viewmodels/login_model.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/services/authentication_service.dart'; -import 'package:provider_architecutre/core/viewmodels/base_model.dart'; - -import '../../locator.dart'; - -class LoginModel extends BaseModel { - final AuthenticationService _authenticationService = locator(); - - String errorMessage; - - Future login(String userIdText) async { - setState(ViewState.Busy); - - var userId = int.tryParse(userIdText); - - // Not a number - if(userId == null) { - errorMessage = 'Value entered is not a number'; - setState(ViewState.Idle); - return false; - } - - var success = await _authenticationService.login(userId); - - // Handle potential error here too. - - setState(ViewState.Idle); - return success; - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/locator.dart b/012-provider-architecture-pt2/1-start/lib/locator.dart deleted file mode 100644 index b1eeac2a..00000000 --- a/012-provider-architecture-pt2/1-start/lib/locator.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:get_it/get_it.dart'; - -import 'core/services/api.dart'; -import 'core/services/authentication_service.dart'; -import 'core/viewmodels/comments_model.dart'; -import 'core/viewmodels/home_model.dart'; -import 'core/viewmodels/login_model.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => Api()); - - locator.registerFactory(() => LoginModel()); - locator.registerFactory(() => HomeModel()); - locator.registerFactory(() => CommentsModel()); -} diff --git a/012-provider-architecture-pt2/1-start/lib/main.dart b/012-provider-architecture-pt2/1-start/lib/main.dart deleted file mode 100644 index 3fc0f524..00000000 --- a/012-provider-architecture-pt2/1-start/lib/main.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/services/authentication_service.dart'; -import 'package:provider_architecutre/locator.dart'; -import 'package:provider_architecutre/ui/router.dart'; - -import 'core/models/user.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return StreamProvider( - initialData: User.initial(), - create: (context) => - locator().userController.stream, - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData(), - initialRoute: 'login', - onGenerateRoute: Router.generateRoute, - ), - ); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/router.dart b/012-provider-architecture-pt2/1-start/lib/ui/router.dart deleted file mode 100644 index e1f1fb3b..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/router.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/ui/views/home_view.dart'; -import 'package:provider_architecutre/ui/views/login_view.dart'; -import 'package:provider_architecutre/ui/views/post_view.dart'; - -const String initialRoute = "login"; - -class Router { - static Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case '/': - return MaterialPageRoute(builder: (_) => HomeView()); - case 'login': - return MaterialPageRoute(builder: (_) => LoginView()); - case 'post': - var post = settings.arguments as Post; - return MaterialPageRoute(builder: (_) => PostView(post: post)); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}'), - ), - )); - } - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/shared/app_colors.dart b/012-provider-architecture-pt2/1-start/lib/ui/shared/app_colors.dart deleted file mode 100644 index 43ad166d..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); -const Color commentColor = Color.fromARGB(255, 255, 246, 196); diff --git a/012-provider-architecture-pt2/1-start/lib/ui/shared/text_styles.dart b/012-provider-architecture-pt2/1-start/lib/ui/shared/text_styles.dart deleted file mode 100644 index 86fec3eb..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/shared/text_styles.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); -const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); \ No newline at end of file diff --git a/012-provider-architecture-pt2/1-start/lib/ui/shared/ui_helpers.dart b/012-provider-architecture-pt2/1-start/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 0259d89b..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 10.0; - static const double _VerticalSpaceMedium = 20.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 10.0; - static const double _HorizontalSpaceMedium = 20.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/views/base_view.dart b/012-provider-architecture-pt2/1-start/lib/ui/views/base_view.dart deleted file mode 100644 index ebca6604..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/views/base_view.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/viewmodels/base_model.dart'; - -import '../../locator.dart'; - -class BaseView extends StatefulWidget { - final Widget Function(BuildContext context, T model, Widget child) builder; - final Function(T) onModelReady; - - BaseView({this.builder, this.onModelReady}); - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T model = locator(); - - @override - void initState() { - if (widget.onModelReady != null) { - widget.onModelReady(model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => model, - child: Consumer(builder: widget.builder)); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/views/home_view.dart b/012-provider-architecture-pt2/1-start/lib/ui/views/home_view.dart deleted file mode 100644 index dc027dfd..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/views/home_view.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/models/user.dart'; -import 'package:provider_architecutre/core/viewmodels/home_model.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/shared/text_styles.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; -import 'package:provider_architecutre/ui/widgets/postlist_item.dart'; - -import 'base_view.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getPosts(Provider.of(context).id), - builder: (context, model, child) => Scaffold( - backgroundColor: backgroundColor, - body: model.state == ViewState.Busy - ? Center(child: CircularProgressIndicator()) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge(), - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text('Welcome ${Provider.of(context).name}', - style: headerStyle,), - ), - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text('Here are all your posts', - style: subHeaderStyle), - ), - UIHelper.verticalSpaceSmall(), - Expanded(child: getPostsUi(model.posts)), - ],) - ), - ); - } - - Widget getPostsUi(List posts) => ListView.builder( - itemCount: posts.length, - itemBuilder: (context, index) => PostListItem( - post: posts[index], - onTap: () { - Navigator.pushNamed(context, 'post', arguments: posts[index]); - }, - ) - ); -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/views/login_view.dart b/012-provider-architecture-pt2/1-start/lib/ui/views/login_view.dart deleted file mode 100644 index a64a710e..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/views/login_view.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/viewmodels/login_model.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/widgets/login_header.dart'; - -import 'base_view.dart'; - -class LoginView extends StatefulWidget { - @override - _LoginViewState createState() => _LoginViewState(); -} - -class _LoginViewState extends State { - final TextEditingController _controller = TextEditingController(); - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, model, child) => Scaffold( - backgroundColor: backgroundColor, - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - LoginHeader( - validationMessage: model.errorMessage, - controller: _controller), - model.state == ViewState.Busy - ? CircularProgressIndicator() - : FlatButton( - color: Colors.white, - child: Text( - 'Login', - style: TextStyle(color: Colors.black), - ), - onPressed: () async { - var loginSuccess = await model.login(_controller.text); - if(loginSuccess){ - Navigator.pushNamed(context, '/'); - } - }, - ) - ],), - ), - ); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/views/post_view.dart b/012-provider-architecture-pt2/1-start/lib/ui/views/post_view.dart deleted file mode 100644 index a94c26c4..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/views/post_view.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/models/user.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/shared/text_styles.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; -import 'package:provider_architecutre/ui/widgets/comments.dart'; - -class PostView extends StatelessWidget { - final Post post; - PostView({this.post}); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge(), - Text(post.title, style: headerStyle), - Text( - 'by ${Provider.of(context).name}', - style: TextStyle(fontSize: 9.0), - ), - UIHelper.verticalSpaceMedium(), - Text(post.body), - Comments(post.id) - ], - ), - ), - ); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/widgets/comments.dart b/012-provider-architecture-pt2/1-start/lib/ui/widgets/comments.dart deleted file mode 100644 index f6ee7659..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/widgets/comments.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/comment.dart'; -import 'package:provider_architecutre/core/viewmodels/comments_model.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; -import 'package:provider_architecutre/ui/views/base_view.dart'; - -class Comments extends StatelessWidget { - final int postId; - Comments(this.postId); - - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.fetchComments(postId), - builder: (context, model, child) => model.state == ViewState.Busy - ? Center(child: CircularProgressIndicator()) - : Expanded(child: ListView( - children: model.comments - .map((comment) => CommentItem(comment)).toList(), - ),) - ); - } -} - -/// Renders a single comment given a comment model -class CommentItem extends StatelessWidget { - final Comment comment; - const CommentItem(this.comment); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.symmetric(vertical: 10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: commentColor), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - comment.name, - style: TextStyle(fontWeight: FontWeight.bold), - ), - UIHelper.verticalSpaceSmall(), - Text(comment.body), - ], - ), - ); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/widgets/login_header.dart b/012-provider-architecture-pt2/1-start/lib/ui/widgets/login_header.dart deleted file mode 100644 index 36815b24..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/widgets/login_header.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/ui/shared/text_styles.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; - -class LoginHeader extends StatelessWidget { - final TextEditingController controller; - final String validationMessage; - - LoginHeader({@required this.controller, this.validationMessage}); - - @override - Widget build(BuildContext context) { - return Column(children: [ - Text('Login', style: headerStyle), - UIHelper.verticalSpaceMedium(), - Text('Enter a number between 1 - 10', style: subHeaderStyle), - LoginTextField(controller), - this.validationMessage != null - ? Text(validationMessage, style: TextStyle(color: Colors.red)) - : Container() - ]); - } -} - -class LoginTextField extends StatelessWidget { - final TextEditingController controller; - - LoginTextField(this.controller); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 15.0), - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), - height: 50.0, - alignment: Alignment.centerLeft, - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - child: TextField( - decoration: InputDecoration.collapsed(hintText: 'User Id'), - controller: controller), - ); - } -} diff --git a/012-provider-architecture-pt2/1-start/lib/ui/widgets/postlist_item.dart b/012-provider-architecture-pt2/1-start/lib/ui/widgets/postlist_item.dart deleted file mode 100644 index 3dcd4d25..00000000 --- a/012-provider-architecture-pt2/1-start/lib/ui/widgets/postlist_item.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/core/models/post.dart'; - -class PostListItem extends StatelessWidget { - final Post post; - final Function onTap; - const PostListItem({this.post, this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.0), - boxShadow: [ - BoxShadow( - blurRadius: 3.0, - offset: Offset(0.0, 2.0), - color: Color.fromARGB(80, 0, 0, 0)) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(post.title, style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0),), - Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) - ], - ), - ), - ); - } -} diff --git a/012-provider-architecture-pt2/1-start/pubspec.lock b/012-provider-architecture-pt2/1-start/pubspec.lock deleted file mode 100644 index 9e337945..00000000 --- a/012-provider-architecture-pt2/1-start/pubspec.lock +++ /dev/null @@ -1,189 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" -sdks: - dart: ">=2.17.0-0 <3.0.0" - flutter: ">=1.16.0" diff --git a/012-provider-architecture-pt2/1-start/pubspec.yaml b/012-provider-architecture-pt2/1-start/pubspec.yaml deleted file mode 100644 index a15b21f2..00000000 --- a/012-provider-architecture-pt2/1-start/pubspec.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: provider_architecutre -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - get_it: ^4.0.2 - http: ">=0.12.1 <0.14.0" - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/012-provider-architecture-pt2/1-start/test/widget_test.dart b/012-provider-architecture-pt2/1-start/test/widget_test.dart deleted file mode 100644 index 48b04eee..00000000 --- a/012-provider-architecture-pt2/1-start/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:provider_architecutre/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/012-provider-architecture-pt2/2-final/.gitignore b/012-provider-architecture-pt2/2-final/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/012-provider-architecture-pt2/2-final/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/012-provider-architecture-pt2/2-final/.metadata b/012-provider-architecture-pt2/2-final/.metadata deleted file mode 100644 index b9fdc6b5..00000000 --- a/012-provider-architecture-pt2/2-final/.metadata +++ /dev/null @@ -1,10 +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: fbe11671a4b78a707d9856588d956c0d3c39a6d5 - channel: master - -project_type: app diff --git a/012-provider-architecture-pt2/2-final/README.md b/012-provider-architecture-pt2/2-final/README.md deleted file mode 100644 index 2d408426..00000000 --- a/012-provider-architecture-pt2/2-final/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Provider + Get_it Architecture - -This is the final result of [this tutorial](https://www.filledstacks.com/post/flutter-architecture-my-provider-implementation-guide) where we setup a Flutter app architecture using the Provider package. \ No newline at end of file diff --git a/012-provider-architecture-pt2/2-final/lib/core/enums/viewstate.dart b/012-provider-architecture-pt2/2-final/lib/core/enums/viewstate.dart deleted file mode 100644 index 08c8932d..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/enums/viewstate.dart +++ /dev/null @@ -1 +0,0 @@ -enum ViewState { Idle, Busy } \ No newline at end of file diff --git a/012-provider-architecture-pt2/2-final/lib/core/models/comment.dart b/012-provider-architecture-pt2/2-final/lib/core/models/comment.dart deleted file mode 100644 index 6a2ebec8..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/models/comment.dart +++ /dev/null @@ -1,27 +0,0 @@ -class Comment { - int postId; - int id; - String name; - String email; - String body; - - Comment({this.postId, this.id, this.name, this.email, this.body}); - - Comment.fromJson(Map json) { - postId = json['postId']; - id = json['id']; - name = json['name']; - email = json['email']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['postId'] = this.postId; - data['id'] = this.id; - data['name'] = this.name; - data['email'] = this.email; - data['body'] = this.body; - return data; - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/2-final/lib/core/models/post.dart b/012-provider-architecture-pt2/2-final/lib/core/models/post.dart deleted file mode 100644 index d85398b8..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/models/post.dart +++ /dev/null @@ -1,27 +0,0 @@ -class Post { - int userId; - int id; - String title; - String body; - int likes; - - Post({this.userId, this.id, this.title, this.body, this.likes = 0}); - - Post.fromJson(Map json) { - userId = json['userId']; - id = json['id']; - title = json['title']; - body = json['body']; - likes = 0; - } - - Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['id'] = this.id; - data['title'] = this.title; - data['body'] = this.body; - data['likes'] = this.likes; - return data; - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/2-final/lib/core/models/user.dart b/012-provider-architecture-pt2/2-final/lib/core/models/user.dart deleted file mode 100644 index 1071dc6c..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/models/user.dart +++ /dev/null @@ -1,25 +0,0 @@ -class User { - int id; - String name; - String username; - User({this.id, this.name, this.username}); - - User.initial() - : id = 0, - name = '', - username = ''; - - User.fromJson(Map json) { - id = json['id']; - name = json['name']; - username = json['username']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['username'] = this.username; - return data; - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/core/services/api.dart b/012-provider-architecture-pt2/2-final/lib/core/services/api.dart deleted file mode 100644 index f763c49b..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/services/api.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:convert'; - -import 'package:provider_architecutre/core/models/comment.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/models/user.dart'; -import 'package:http/http.dart' as http; - -/// The service responsible for networking requests -class Api { - static const endpoint = 'https://jsonplaceholder.typicode.com'; - - var client = new http.Client(); - - Future getUserProfile(int userId) async { - // Get user profile for id - var response = await client.get('$endpoint/users/$userId'); - - // Convert and return - return User.fromJson(json.decode(response.body)); - } - - Future> getPostsForUser(int userId) async { - var posts = List(); - // Get user posts for id - var response = await client.get('$endpoint/posts?userId=$userId'); - - // parse into List - var parsed = json.decode(response.body) as List; - - // loop and convert each item to Post - for (var post in parsed) { - posts.add(Post.fromJson(post)); - } - - return posts; - } - - Future> getCommentsForPost(int postId) async { - var comments = List(); - - // Get comments for post - var response = await client.get('$endpoint/comments?postId=$postId'); - - // Parse into List - var parsed = json.decode(response.body) as List; - - // Loop and convert each item to a Comment - for (var comment in parsed) { - comments.add(Comment.fromJson(comment)); - } - - return comments; - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/core/services/authentication_service.dart b/012-provider-architecture-pt2/2-final/lib/core/services/authentication_service.dart deleted file mode 100644 index 90c322cb..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/services/authentication_service.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'dart:async'; - -import 'package:provider_architecutre/core/models/user.dart'; - -import '../../locator.dart'; -import 'api.dart'; - -class AuthenticationService { - Api _api = locator(); - - StreamController userController = StreamController(); - - Future login(int userId) async { - var fetchedUser = await _api.getUserProfile(userId); - - var hasUser = fetchedUser != null; - if(hasUser) { - userController.add(fetchedUser); - } - - return hasUser; - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/2-final/lib/core/services/posts_service.dart b/012-provider-architecture-pt2/2-final/lib/core/services/posts_service.dart deleted file mode 100644 index ca8fc327..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/services/posts_service.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:provider_architecutre/core/models/post.dart'; - -import '../../locator.dart'; -import 'api.dart'; - -class PostsService { - Api _api = locator(); - - List _posts; - List get posts => _posts; - - Future getPostsForUser(int userId) async { - _posts = await _api.getPostsForUser(userId); - } - - void incrementLikes(int postId){ - _posts.firstWhere((post) => post.id == postId).likes++; - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/base_model.dart b/012-provider-architecture-pt2/2-final/lib/core/viewmodels/base_model.dart deleted file mode 100644 index 4da436d2..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/base_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; - -class BaseModel extends ChangeNotifier { - ViewState _state = ViewState.Idle; - - ViewState get state => _state; - - void setState(ViewState viewState) { - _state = viewState; - notifyListeners(); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/comments_model.dart b/012-provider-architecture-pt2/2-final/lib/core/viewmodels/comments_model.dart deleted file mode 100644 index 77cb8de4..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/comments_model.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/comment.dart'; -import 'package:provider_architecutre/core/services/api.dart'; - -import '../../locator.dart'; -import 'base_model.dart'; - -class CommentsModel extends BaseModel { - Api _api = locator(); - - List comments; - - Future fetchComments(int postId) async { - setState(ViewState.Busy); - comments = await _api.getCommentsForPost(postId); - setState(ViewState.Idle); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/home_model.dart b/012-provider-architecture-pt2/2-final/lib/core/viewmodels/home_model.dart deleted file mode 100644 index 15c44654..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/home_model.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/services/posts_service.dart'; -import 'package:provider_architecutre/locator.dart'; - -import 'base_model.dart'; - -class HomeModel extends BaseModel { - PostsService _postsService = locator(); - - List get posts => _postsService.posts; - - Future getPosts(int userId) async { - setState(ViewState.Busy); - await _postsService.getPostsForUser(userId); - setState(ViewState.Idle); - } -} \ No newline at end of file diff --git a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/like_button_model.dart b/012-provider-architecture-pt2/2-final/lib/core/viewmodels/like_button_model.dart deleted file mode 100644 index e7550d97..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/like_button_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:provider_architecutre/core/services/posts_service.dart'; -import 'package:provider_architecutre/locator.dart'; - -import 'base_model.dart'; - -class LikeButtonModel extends BaseModel { - PostsService _postsService = locator(); - - int postLikes(int postId) { - return _postsService.posts - .firstWhere((post) => post.id == postId) - .likes; - } - - void increaseLikes(int postId) { - _postsService.incrementLikes(postId); - notifyListeners(); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/login_model.dart b/012-provider-architecture-pt2/2-final/lib/core/viewmodels/login_model.dart deleted file mode 100644 index e690c2e3..00000000 --- a/012-provider-architecture-pt2/2-final/lib/core/viewmodels/login_model.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/services/authentication_service.dart'; -import 'package:provider_architecutre/core/viewmodels/base_model.dart'; - -import '../../locator.dart'; - -class LoginModel extends BaseModel { - final AuthenticationService _authenticationService = locator(); - - String errorMessage; - - Future login(String userIdText) async { - setState(ViewState.Busy); - - var userId = int.tryParse(userIdText); - - // Not a number - if(userId == null) { - errorMessage = 'Value entered is not a number'; - setState(ViewState.Idle); - return false; - } - - var success = await _authenticationService.login(userId); - - // Handle potential error here too. - - setState(ViewState.Idle); - return success; - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/locator.dart b/012-provider-architecture-pt2/2-final/lib/locator.dart deleted file mode 100644 index d2d9815e..00000000 --- a/012-provider-architecture-pt2/2-final/lib/locator.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:provider_architecutre/core/services/posts_service.dart'; -import 'package:provider_architecutre/core/viewmodels/like_button_model.dart'; - -import 'core/services/api.dart'; -import 'core/services/authentication_service.dart'; -import 'core/viewmodels/comments_model.dart'; -import 'core/viewmodels/home_model.dart'; -import 'core/viewmodels/login_model.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => PostsService()); - locator.registerLazySingleton(() => Api()); - - locator.registerFactory(() => LoginModel()); - locator.registerFactory(() => LikeButtonModel()); - locator.registerFactory(() => HomeModel()); - locator.registerFactory(() => CommentsModel()); -} diff --git a/012-provider-architecture-pt2/2-final/lib/main.dart b/012-provider-architecture-pt2/2-final/lib/main.dart deleted file mode 100644 index 3fc0f524..00000000 --- a/012-provider-architecture-pt2/2-final/lib/main.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/services/authentication_service.dart'; -import 'package:provider_architecutre/locator.dart'; -import 'package:provider_architecutre/ui/router.dart'; - -import 'core/models/user.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return StreamProvider( - initialData: User.initial(), - create: (context) => - locator().userController.stream, - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData(), - initialRoute: 'login', - onGenerateRoute: Router.generateRoute, - ), - ); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/router.dart b/012-provider-architecture-pt2/2-final/lib/ui/router.dart deleted file mode 100644 index e1f1fb3b..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/router.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/ui/views/home_view.dart'; -import 'package:provider_architecutre/ui/views/login_view.dart'; -import 'package:provider_architecutre/ui/views/post_view.dart'; - -const String initialRoute = "login"; - -class Router { - static Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case '/': - return MaterialPageRoute(builder: (_) => HomeView()); - case 'login': - return MaterialPageRoute(builder: (_) => LoginView()); - case 'post': - var post = settings.arguments as Post; - return MaterialPageRoute(builder: (_) => PostView(post: post)); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}'), - ), - )); - } - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/shared/app_colors.dart b/012-provider-architecture-pt2/2-final/lib/ui/shared/app_colors.dart deleted file mode 100644 index 43ad166d..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); -const Color commentColor = Color.fromARGB(255, 255, 246, 196); diff --git a/012-provider-architecture-pt2/2-final/lib/ui/shared/text_styles.dart b/012-provider-architecture-pt2/2-final/lib/ui/shared/text_styles.dart deleted file mode 100644 index 86fec3eb..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/shared/text_styles.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); -const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); \ No newline at end of file diff --git a/012-provider-architecture-pt2/2-final/lib/ui/shared/ui_helpers.dart b/012-provider-architecture-pt2/2-final/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 0259d89b..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; - -/// Contains useful functions to reduce boilerplate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 10.0; - static const double _VerticalSpaceMedium = 20.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 10.0; - static const double _HorizontalSpaceMedium = 20.0; - static const double HorizontalSpaceLarge = 60.0; - - /// Returns a vertical space with height set to [_VerticalSpaceSmall] - static Widget verticalSpaceSmall() { - return verticalSpace(_VerticalSpaceSmall); - } - - /// Returns a vertical space with height set to [_VerticalSpaceMedium] - static Widget verticalSpaceMedium() { - return verticalSpace(_VerticalSpaceMedium); - } - - /// Returns a vertical space with height set to [_VerticalSpaceLarge] - static Widget verticalSpaceLarge() { - return verticalSpace(_VerticalSpaceLarge); - } - - /// Returns a vertical space equal to the [height] supplied - static Widget verticalSpace(double height) { - return Container(height: height); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceSmall] - static Widget horizontalSpaceSmall() { - return horizontalSpace(_HorizontalSpaceSmall); - } - - /// Returns a vertical space with height set to [_HorizontalSpaceMedium] - static Widget horizontalSpaceMedium() { - return horizontalSpace(_HorizontalSpaceMedium); - } - - /// Returns a vertical space with height set to [HorizontalSpaceLarge] - static Widget horizontalSpaceLarge() { - return horizontalSpace(HorizontalSpaceLarge); - } - - /// Returns a vertical space equal to the [width] supplied - static Widget horizontalSpace(double width) { - return Container(width: width); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/views/base_view.dart b/012-provider-architecture-pt2/2-final/lib/ui/views/base_view.dart deleted file mode 100644 index ebca6604..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/views/base_view.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/viewmodels/base_model.dart'; - -import '../../locator.dart'; - -class BaseView extends StatefulWidget { - final Widget Function(BuildContext context, T model, Widget child) builder; - final Function(T) onModelReady; - - BaseView({this.builder, this.onModelReady}); - - @override - _BaseViewState createState() => _BaseViewState(); -} - -class _BaseViewState extends State> { - T model = locator(); - - @override - void initState() { - if (widget.onModelReady != null) { - widget.onModelReady(model); - } - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => model, - child: Consumer(builder: widget.builder)); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/views/home_view.dart b/012-provider-architecture-pt2/2-final/lib/ui/views/home_view.dart deleted file mode 100644 index dc027dfd..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/views/home_view.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/models/user.dart'; -import 'package:provider_architecutre/core/viewmodels/home_model.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/shared/text_styles.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; -import 'package:provider_architecutre/ui/widgets/postlist_item.dart'; - -import 'base_view.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.getPosts(Provider.of(context).id), - builder: (context, model, child) => Scaffold( - backgroundColor: backgroundColor, - body: model.state == ViewState.Busy - ? Center(child: CircularProgressIndicator()) - : Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge(), - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text('Welcome ${Provider.of(context).name}', - style: headerStyle,), - ), - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text('Here are all your posts', - style: subHeaderStyle), - ), - UIHelper.verticalSpaceSmall(), - Expanded(child: getPostsUi(model.posts)), - ],) - ), - ); - } - - Widget getPostsUi(List posts) => ListView.builder( - itemCount: posts.length, - itemBuilder: (context, index) => PostListItem( - post: posts[index], - onTap: () { - Navigator.pushNamed(context, 'post', arguments: posts[index]); - }, - ) - ); -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/views/login_view.dart b/012-provider-architecture-pt2/2-final/lib/ui/views/login_view.dart deleted file mode 100644 index a64a710e..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/views/login_view.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/viewmodels/login_model.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/widgets/login_header.dart'; - -import 'base_view.dart'; - -class LoginView extends StatefulWidget { - @override - _LoginViewState createState() => _LoginViewState(); -} - -class _LoginViewState extends State { - final TextEditingController _controller = TextEditingController(); - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, model, child) => Scaffold( - backgroundColor: backgroundColor, - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - LoginHeader( - validationMessage: model.errorMessage, - controller: _controller), - model.state == ViewState.Busy - ? CircularProgressIndicator() - : FlatButton( - color: Colors.white, - child: Text( - 'Login', - style: TextStyle(color: Colors.black), - ), - onPressed: () async { - var loginSuccess = await model.login(_controller.text); - if(loginSuccess){ - Navigator.pushNamed(context, '/'); - } - }, - ) - ],), - ), - ); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/views/post_view.dart b/012-provider-architecture-pt2/2-final/lib/ui/views/post_view.dart deleted file mode 100644 index afc1c3a0..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/views/post_view.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_architecutre/core/models/post.dart'; -import 'package:provider_architecutre/core/models/user.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/shared/text_styles.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; -import 'package:provider_architecutre/ui/widgets/comments.dart'; -import 'package:provider_architecutre/ui/widgets/like_button.dart'; - -class PostView extends StatelessWidget { - final Post post; - PostView({this.post}); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge(), - Text(post.title, style: headerStyle), - Text( - 'by ${Provider.of(context).name}', - style: TextStyle(fontSize: 9.0), - ), - UIHelper.verticalSpaceMedium(), - Text(post.body), - LikeButton(postId: post.id,), - Comments(post.id) - ], - ), - ), - ); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/views/tab_container.dart b/012-provider-architecture-pt2/2-final/lib/ui/views/tab_container.dart deleted file mode 100644 index f126caaf..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/views/tab_container.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/ui/views/home_view.dart'; - -import 'login_view.dart'; - -class TabContainer extends StatelessWidget { - const TabContainer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return DefaultTabController( - length: 2, - child: Scaffold( - appBar: AppBar( - bottom: TabBar( - tabs: [ - Tab(icon: Icon(Icons.directions_car)), - Tab(icon: Icon(Icons.directions_transit)), - ], - ), - title: Text('Tabs Demo'), - ), - body: TabBarView( - children: [ - LoginView(), - HomeView(), - ], - ), - ), - ); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/widgets/comments.dart b/012-provider-architecture-pt2/2-final/lib/ui/widgets/comments.dart deleted file mode 100644 index f6ee7659..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/widgets/comments.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/core/enums/viewstate.dart'; -import 'package:provider_architecutre/core/models/comment.dart'; -import 'package:provider_architecutre/core/viewmodels/comments_model.dart'; -import 'package:provider_architecutre/ui/shared/app_colors.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; -import 'package:provider_architecutre/ui/views/base_view.dart'; - -class Comments extends StatelessWidget { - final int postId; - Comments(this.postId); - - @override - Widget build(BuildContext context) { - return BaseView( - onModelReady: (model) => model.fetchComments(postId), - builder: (context, model, child) => model.state == ViewState.Busy - ? Center(child: CircularProgressIndicator()) - : Expanded(child: ListView( - children: model.comments - .map((comment) => CommentItem(comment)).toList(), - ),) - ); - } -} - -/// Renders a single comment given a comment model -class CommentItem extends StatelessWidget { - final Comment comment; - const CommentItem(this.comment); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.symmetric(vertical: 10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: commentColor), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - comment.name, - style: TextStyle(fontWeight: FontWeight.bold), - ), - UIHelper.verticalSpaceSmall(), - Text(comment.body), - ], - ), - ); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/widgets/like_button.dart b/012-provider-architecture-pt2/2-final/lib/ui/widgets/like_button.dart deleted file mode 100644 index 8f256c44..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/widgets/like_button.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/core/viewmodels/like_button_model.dart'; -import 'package:provider_architecutre/ui/views/base_view.dart'; - -class LikeButton extends StatelessWidget { - final int postId; - - LikeButton({ - @required this.postId, - }); - - @override - Widget build(BuildContext context) { - return BaseView( - builder: (context, model, child) => Row( - children: [ - Text('Likes ${model.postLikes(postId)}'), - MaterialButton( - color: Colors.white, - child: Icon(Icons.thumb_up), - onPressed: () { - model.increaseLikes(postId); - }, - ) - ], - )); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/widgets/login_header.dart b/012-provider-architecture-pt2/2-final/lib/ui/widgets/login_header.dart deleted file mode 100644 index 36815b24..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/widgets/login_header.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/ui/shared/text_styles.dart'; -import 'package:provider_architecutre/ui/shared/ui_helpers.dart'; - -class LoginHeader extends StatelessWidget { - final TextEditingController controller; - final String validationMessage; - - LoginHeader({@required this.controller, this.validationMessage}); - - @override - Widget build(BuildContext context) { - return Column(children: [ - Text('Login', style: headerStyle), - UIHelper.verticalSpaceMedium(), - Text('Enter a number between 1 - 10', style: subHeaderStyle), - LoginTextField(controller), - this.validationMessage != null - ? Text(validationMessage, style: TextStyle(color: Colors.red)) - : Container() - ]); - } -} - -class LoginTextField extends StatelessWidget { - final TextEditingController controller; - - LoginTextField(this.controller); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 15.0), - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), - height: 50.0, - alignment: Alignment.centerLeft, - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - child: TextField( - decoration: InputDecoration.collapsed(hintText: 'User Id'), - controller: controller), - ); - } -} diff --git a/012-provider-architecture-pt2/2-final/lib/ui/widgets/postlist_item.dart b/012-provider-architecture-pt2/2-final/lib/ui/widgets/postlist_item.dart deleted file mode 100644 index 3d2d6fbc..00000000 --- a/012-provider-architecture-pt2/2-final/lib/ui/widgets/postlist_item.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_architecutre/core/models/post.dart'; - -class PostListItem extends StatelessWidget { - final Post post; - final Function onTap; - const PostListItem({this.post, this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.0), - boxShadow: [ - BoxShadow( - blurRadius: 3.0, - offset: Offset(0.0, 2.0), - color: Color.fromARGB(80, 0, 0, 0)) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - '${post.title} - ${post.likes.toString()}', - maxLines: 2, - style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0), - ), - Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) - ], - ), - ), - ); - } -} diff --git a/012-provider-architecture-pt2/2-final/pubspec.lock b/012-provider-architecture-pt2/2-final/pubspec.lock deleted file mode 100644 index f665143c..00000000 --- a/012-provider-architecture-pt2/2-final/pubspec.lock +++ /dev/null @@ -1,189 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/012-provider-architecture-pt2/2-final/pubspec.yaml b/012-provider-architecture-pt2/2-final/pubspec.yaml deleted file mode 100644 index 633541f6..00000000 --- a/012-provider-architecture-pt2/2-final/pubspec.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: provider_architecutre -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - get_it: ^4.0.2 - http: ^0.12.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/012-provider-architecture-pt2/2-final/test/widget_test.dart b/012-provider-architecture-pt2/2-final/test/widget_test.dart deleted file mode 100644 index 48b04eee..00000000 --- a/012-provider-architecture-pt2/2-final/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:provider_architecutre/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/013-dependency-injection/1-start/.gitignore b/013-dependency-injection/1-start/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/013-dependency-injection/1-start/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/013-dependency-injection/1-start/.metadata b/013-dependency-injection/1-start/.metadata deleted file mode 100644 index a99c5c1b..00000000 --- a/013-dependency-injection/1-start/.metadata +++ /dev/null @@ -1,10 +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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b - channel: stable - -project_type: app diff --git a/013-dependency-injection/1-start/README.md b/013-dependency-injection/1-start/README.md deleted file mode 100644 index 89e02e17..00000000 --- a/013-dependency-injection/1-start/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# dependency_injection - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/013-dependency-injection/1-start/lib/home_view.dart b/013-dependency-injection/1-start/lib/home_view.dart deleted file mode 100644 index 0fe9facf..00000000 --- a/013-dependency-injection/1-start/lib/home_view.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Text('Text'), - ), - ); - } -} diff --git a/013-dependency-injection/1-start/lib/main.dart b/013-dependency-injection/1-start/lib/main.dart deleted file mode 100644 index 2a290c4f..00000000 --- a/013-dependency-injection/1-start/lib/main.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Dependency Injection', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Scaffold(), - ); - } -} diff --git a/013-dependency-injection/1-start/pubspec.lock b/013-dependency-injection/1-start/pubspec.lock deleted file mode 100644 index 2e161248..00000000 --- a/013-dependency-injection/1-start/pubspec.lock +++ /dev/null @@ -1,146 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/013-dependency-injection/1-start/pubspec.yaml b/013-dependency-injection/1-start/pubspec.yaml deleted file mode 100644 index d2f8c1e6..00000000 --- a/013-dependency-injection/1-start/pubspec.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: dependency_injection -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/013-dependency-injection/1-start/test/widget_test.dart b/013-dependency-injection/1-start/test/widget_test.dart deleted file mode 100644 index 29412127..00000000 --- a/013-dependency-injection/1-start/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:dependency_injection/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/013-dependency-injection/2-final/.gitignore b/013-dependency-injection/2-final/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/013-dependency-injection/2-final/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/013-dependency-injection/2-final/.metadata b/013-dependency-injection/2-final/.metadata deleted file mode 100644 index a99c5c1b..00000000 --- a/013-dependency-injection/2-final/.metadata +++ /dev/null @@ -1,10 +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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b - channel: stable - -project_type: app diff --git a/013-dependency-injection/2-final/README.md b/013-dependency-injection/2-final/README.md deleted file mode 100644 index 89e02e17..00000000 --- a/013-dependency-injection/2-final/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# dependency_injection - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/013-dependency-injection/2-final/lib/app_info.dart b/013-dependency-injection/2-final/lib/app_info.dart deleted file mode 100644 index 7349fbad..00000000 --- a/013-dependency-injection/2-final/lib/app_info.dart +++ /dev/null @@ -1,3 +0,0 @@ -class AppInfo { - String get welcomeMessage => 'Hello from FilledStacks'; -} \ No newline at end of file diff --git a/013-dependency-injection/2-final/lib/home_view.dart b/013-dependency-injection/2-final/lib/home_view.dart deleted file mode 100644 index a6167e68..00000000 --- a/013-dependency-injection/2-final/lib/home_view.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -import 'app_info.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold(body: MyList()); - } -} - -class MyList extends StatelessWidget { - const MyList({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return PostItem(); - } -} - -class PostItem extends StatelessWidget { - const PostItem({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return PostMenu(); - } -} - -class PostMenu extends StatelessWidget { - const PostMenu({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return PostAction(); - } -} - -class PostAction extends StatelessWidget { - const PostAction({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LikeButton(); - } -} - -class LikeButton extends StatelessWidget { - const LikeButton({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - // We have access to it anywhere in the app with this simple call - var appInfo = Provider.of(context); - return Container( - child: Text(appInfo.welcomeMessage), - ); - } -} diff --git a/013-dependency-injection/2-final/lib/inherited_injection.dart b/013-dependency-injection/2-final/lib/inherited_injection.dart deleted file mode 100644 index 55813afa..00000000 --- a/013-dependency-injection/2-final/lib/inherited_injection.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:dependency_injection/app_info.dart'; -import 'package:flutter/material.dart'; - -class InheritedInjection extends InheritedWidget { - final AppInfo _appInfo = AppInfo(); - final Widget child; - - InheritedInjection({Key key, this.child}) : super(key: key, child: child); - - AppInfo get appInfo => _appInfo; - - static InheritedInjection of(BuildContext context) { - return (context.dependOnInheritedWidgetOfExactType()); - } - - @override - bool updateShouldNotify(InheritedInjection oldWidget) { - return true; - } -} diff --git a/013-dependency-injection/2-final/lib/locator.dart b/013-dependency-injection/2-final/lib/locator.dart deleted file mode 100644 index cc0ac679..00000000 --- a/013-dependency-injection/2-final/lib/locator.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:get_it/get_it.dart'; - -import 'app_info.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerFactory(() => AppInfo()); -} diff --git a/013-dependency-injection/2-final/lib/main.dart b/013-dependency-injection/2-final/lib/main.dart deleted file mode 100644 index 2855fde6..00000000 --- a/013-dependency-injection/2-final/lib/main.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:dependency_injection/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'app_info.dart'; -import 'locator.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Provider( - create: (context) => AppInfo(), - child: MaterialApp( - title: 'Dependency Injection', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Scaffold( - body: HomeView(), - ), - ), - ); - } -} diff --git a/013-dependency-injection/2-final/pubspec.lock b/013-dependency-injection/2-final/pubspec.lock deleted file mode 100644 index 3e1ebe13..00000000 --- a/013-dependency-injection/2-final/pubspec.lock +++ /dev/null @@ -1,168 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/013-dependency-injection/2-final/pubspec.yaml b/013-dependency-injection/2-final/pubspec.yaml deleted file mode 100644 index e5fbc745..00000000 --- a/013-dependency-injection/2-final/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: dependency_injection -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - get_it: ^4.0.2 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/013-dependency-injection/2-final/test/widget_test.dart b/013-dependency-injection/2-final/test/widget_test.dart deleted file mode 100644 index 29412127..00000000 --- a/013-dependency-injection/2-final/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:dependency_injection/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/014-provider-v3-updates/1-start/.gitignore b/014-provider-v3-updates/1-start/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/014-provider-v3-updates/1-start/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/014-provider-v3-updates/1-start/.metadata b/014-provider-v3-updates/1-start/.metadata deleted file mode 100644 index a99c5c1b..00000000 --- a/014-provider-v3-updates/1-start/.metadata +++ /dev/null @@ -1,10 +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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b - channel: stable - -project_type: app diff --git a/014-provider-v3-updates/1-start/README.md b/014-provider-v3-updates/1-start/README.md deleted file mode 100644 index 9d91bc31..00000000 --- a/014-provider-v3-updates/1-start/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# provider_arc - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/014-provider-v3-updates/1-start/lib/core/constants/app_contstants.dart b/014-provider-v3-updates/1-start/lib/core/constants/app_contstants.dart deleted file mode 100644 index 58f884e5..00000000 --- a/014-provider-v3-updates/1-start/lib/core/constants/app_contstants.dart +++ /dev/null @@ -1,9 +0,0 @@ - -// You can also just let this float around in the file without encapsulating -// in a class. Then you'll have to make sure that system wide you don't have -// duplicate variable names. -class RoutePaths { - static const String Login = 'login'; - static const String Home = '/'; - static const String Post = 'post'; -} \ No newline at end of file diff --git a/014-provider-v3-updates/1-start/lib/core/models/comment.dart b/014-provider-v3-updates/1-start/lib/core/models/comment.dart deleted file mode 100644 index 6a2ebec8..00000000 --- a/014-provider-v3-updates/1-start/lib/core/models/comment.dart +++ /dev/null @@ -1,27 +0,0 @@ -class Comment { - int postId; - int id; - String name; - String email; - String body; - - Comment({this.postId, this.id, this.name, this.email, this.body}); - - Comment.fromJson(Map json) { - postId = json['postId']; - id = json['id']; - name = json['name']; - email = json['email']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['postId'] = this.postId; - data['id'] = this.id; - data['name'] = this.name; - data['email'] = this.email; - data['body'] = this.body; - return data; - } -} \ No newline at end of file diff --git a/014-provider-v3-updates/1-start/lib/core/models/post.dart b/014-provider-v3-updates/1-start/lib/core/models/post.dart deleted file mode 100644 index c1c6cf92..00000000 --- a/014-provider-v3-updates/1-start/lib/core/models/post.dart +++ /dev/null @@ -1,24 +0,0 @@ -class Post { - int userId; - int id; - String title; - String body; - - Post({this.userId, this.id, this.title, this.body}); - - Post.fromJson(Map json) { - userId = json['userId']; - id = json['id']; - title = json['title']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['id'] = this.id; - data['title'] = this.title; - data['body'] = this.body; - return data; - } -} \ No newline at end of file diff --git a/014-provider-v3-updates/1-start/lib/core/models/user.dart b/014-provider-v3-updates/1-start/lib/core/models/user.dart deleted file mode 100644 index 1071dc6c..00000000 --- a/014-provider-v3-updates/1-start/lib/core/models/user.dart +++ /dev/null @@ -1,25 +0,0 @@ -class User { - int id; - String name; - String username; - User({this.id, this.name, this.username}); - - User.initial() - : id = 0, - name = '', - username = ''; - - User.fromJson(Map json) { - id = json['id']; - name = json['name']; - username = json['username']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['username'] = this.username; - return data; - } -} diff --git a/014-provider-v3-updates/1-start/lib/core/services/api.dart b/014-provider-v3-updates/1-start/lib/core/services/api.dart deleted file mode 100644 index 71f1e5db..00000000 --- a/014-provider-v3-updates/1-start/lib/core/services/api.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:convert'; - -import 'package:http/http.dart' as http; -import 'package:provider_arc/core/models/comment.dart'; -import 'package:provider_arc/core/models/post.dart'; -import 'package:provider_arc/core/models/user.dart'; - -/// The service responsible for networking requests -class Api { - static const endpoint = 'https://jsonplaceholder.typicode.com'; - - var client = new http.Client(); - - Future getUserProfile(int userId) async { - // Get user profile for id - var response = await client.get('$endpoint/users/$userId'); - - // Convert and return - return User.fromJson(json.decode(response.body)); - } - - Future> getPostsForUser(int userId) async { - var posts = List(); - // Get user posts for id - var response = await client.get('$endpoint/posts?userId=$userId'); - - // parse into List - var parsed = json.decode(response.body) as List; - - // loop and convert each item to Post - for (var post in parsed) { - posts.add(Post.fromJson(post)); - } - - return posts; - } - - Future> getCommentsForPost(int postId) async { - var comments = List(); - - // Get comments for post - var response = await client.get('$endpoint/comments?postId=$postId'); - - // Parse into List - var parsed = json.decode(response.body) as List; - - // Loop and convert each item to a Comment - for (var comment in parsed) { - comments.add(Comment.fromJson(comment)); - } - - return comments; - } -} diff --git a/014-provider-v3-updates/1-start/lib/core/services/authentication_service.dart b/014-provider-v3-updates/1-start/lib/core/services/authentication_service.dart deleted file mode 100644 index 63e2ca66..00000000 --- a/014-provider-v3-updates/1-start/lib/core/services/authentication_service.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'dart:async'; - -import 'package:provider_arc/core/models/user.dart'; -import 'package:provider_arc/core/services/api.dart'; - -class AuthenticationService { - final Api _api; - - AuthenticationService({Api api}) : _api = api; - - StreamController _userController = StreamController(); - - Stream get user => _userController.stream; - - Future login(int userId) async { - var fetchedUser = await _api.getUserProfile(userId); - - var hasUser = fetchedUser != null; - if (hasUser) { - _userController.add(fetchedUser); - } - - return hasUser; - } -} diff --git a/014-provider-v3-updates/1-start/lib/main.dart b/014-provider-v3-updates/1-start/lib/main.dart deleted file mode 100644 index af19d24f..00000000 --- a/014-provider-v3-updates/1-start/lib/main.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/ui/router.dart'; - -import 'core/constants/app_contstants.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - initialRoute: RoutePaths.Login, - onGenerateRoute: Router.generateRoute, - ); - } -} diff --git a/014-provider-v3-updates/1-start/lib/ui/router.dart b/014-provider-v3-updates/1-start/lib/ui/router.dart deleted file mode 100644 index cbadfebd..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/router.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider_arc/core/constants/app_contstants.dart'; -import 'package:provider_arc/core/models/post.dart'; -import 'package:provider_arc/ui/views/home_view.dart'; -import 'package:provider_arc/ui/views/login_view.dart'; -import 'package:provider_arc/ui/views/post_view.dart'; - -class Router { - static Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case RoutePaths.Home: - return MaterialPageRoute(builder: (_) => HomeView()); - case RoutePaths.Login: - return MaterialPageRoute(builder: (_) => LoginView()); - case RoutePaths.Post: - var post = settings.arguments as Post; - return MaterialPageRoute(builder: (_) => PostView(post: post)); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}'), - ), - )); - } - } -} diff --git a/014-provider-v3-updates/1-start/lib/ui/shared/app_colors.dart b/014-provider-v3-updates/1-start/lib/ui/shared/app_colors.dart deleted file mode 100644 index 43ad166d..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); -const Color commentColor = Color.fromARGB(255, 255, 246, 196); diff --git a/014-provider-v3-updates/1-start/lib/ui/shared/text_styles.dart b/014-provider-v3-updates/1-start/lib/ui/shared/text_styles.dart deleted file mode 100644 index 86fec3eb..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/shared/text_styles.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); -const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); \ No newline at end of file diff --git a/014-provider-v3-updates/1-start/lib/ui/shared/ui_helpers.dart b/014-provider-v3-updates/1-start/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 29cfb895..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -/// Contains useful consts to reduce boilerplate and duplicate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 10.0; - static const double _VerticalSpaceMedium = 20.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 10.0; - static const double _HorizontalSpaceMedium = 20.0; - static const double _HorizontalSpaceLarge = 60.0; - - static const Widget verticalSpaceSmall = SizedBox(height: _VerticalSpaceSmall); - static const Widget verticalSpaceMedium = SizedBox(height: _VerticalSpaceMedium); - static const Widget verticalSpaceLarge = SizedBox(height: _VerticalSpaceLarge); - - static const Widget horizontalSpaceSmall = SizedBox(width: _HorizontalSpaceSmall); - static const Widget horizontalSpaceMedium = SizedBox(width: _HorizontalSpaceMedium); - static const Widget horizontalSpaceLarge = SizedBox(width: _HorizontalSpaceLarge); -} diff --git a/014-provider-v3-updates/1-start/lib/ui/views/home_view.dart b/014-provider-v3-updates/1-start/lib/ui/views/home_view.dart deleted file mode 100644 index f5ab96e0..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/views/home_view.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Center(child: Text('Home View'))); - } -} diff --git a/014-provider-v3-updates/1-start/lib/ui/views/login_view.dart b/014-provider-v3-updates/1-start/lib/ui/views/login_view.dart deleted file mode 100644 index ccfe9b68..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/views/login_view.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; - -class LoginView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Center(child: Text('Login View'))); - } -} diff --git a/014-provider-v3-updates/1-start/lib/ui/views/post_view.dart b/014-provider-v3-updates/1-start/lib/ui/views/post_view.dart deleted file mode 100644 index 0ebbfddc..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/views/post_view.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/core/models/post.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; - -class PostView extends StatelessWidget { - final Post post; - const PostView({Key key, this.post}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Center(child: Text('Post View'))); - } -} diff --git a/014-provider-v3-updates/1-start/lib/ui/widgets/comments.dart b/014-provider-v3-updates/1-start/lib/ui/widgets/comments.dart deleted file mode 100644 index 3397283b..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/widgets/comments.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/core/models/comment.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; -import 'package:provider_arc/ui/shared/ui_helpers.dart'; - -class Comments extends StatelessWidget { - final int postId; - Comments(this.postId); - - @override - Widget build(BuildContext context) { - return Container(); - } -} - -/// Renders a single comment given a comment model -class CommentItem extends StatelessWidget { - final Comment comment; - const CommentItem(this.comment); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.symmetric(vertical: 10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: commentColor), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - comment.name, - style: TextStyle(fontWeight: FontWeight.bold), - ), - UIHelper.verticalSpaceSmall, - Text(comment.body), - ], - ), - ); - } -} diff --git a/014-provider-v3-updates/1-start/lib/ui/widgets/login_header.dart b/014-provider-v3-updates/1-start/lib/ui/widgets/login_header.dart deleted file mode 100644 index 825e58d9..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/widgets/login_header.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/ui/shared/text_styles.dart'; -import 'package:provider_arc/ui/shared/ui_helpers.dart'; - -class LoginHeader extends StatelessWidget { - final TextEditingController controller; - final String validationMessage; - - LoginHeader({@required this.controller, this.validationMessage}); - - @override - Widget build(BuildContext context) { - return Column(children: [ - Text('Login', style: headerStyle), - UIHelper.verticalSpaceMedium, - Text('Enter a number between 1 - 10', style: subHeaderStyle), - LoginTextField(controller), - this.validationMessage != null - ? Text(validationMessage, style: TextStyle(color: Colors.red)) - : Container() - ]); - } -} - -class LoginTextField extends StatelessWidget { - final TextEditingController controller; - - LoginTextField(this.controller); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 15.0), - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), - height: 50.0, - alignment: Alignment.centerLeft, - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - child: TextField( - decoration: InputDecoration.collapsed(hintText: 'User Id'), - controller: controller), - ); - } -} diff --git a/014-provider-v3-updates/1-start/lib/ui/widgets/postlist_item.dart b/014-provider-v3-updates/1-start/lib/ui/widgets/postlist_item.dart deleted file mode 100644 index 7318c4c4..00000000 --- a/014-provider-v3-updates/1-start/lib/ui/widgets/postlist_item.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/core/models/post.dart'; - -class PostListItem extends StatelessWidget { - final Post post; - final Function onTap; - const PostListItem({this.post, this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.0), - boxShadow: [ - BoxShadow( - blurRadius: 3.0, - offset: Offset(0.0, 2.0), - color: Color.fromARGB(80, 0, 0, 0)) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(post.title, style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0),), - Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) - ], - ), - ), - ); - } -} diff --git a/014-provider-v3-updates/1-start/pubspec.lock b/014-provider-v3-updates/1-start/pubspec.lock deleted file mode 100644 index ab9e6f8a..00000000 --- a/014-provider-v3-updates/1-start/pubspec.lock +++ /dev/null @@ -1,167 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" -sdks: - dart: ">=2.17.0-0 <3.0.0" diff --git a/014-provider-v3-updates/1-start/pubspec.yaml b/014-provider-v3-updates/1-start/pubspec.yaml deleted file mode 100644 index 7441cb89..00000000 --- a/014-provider-v3-updates/1-start/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: provider_arc -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - http: ">=0.12.1 <0.14.0" - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/014-provider-v3-updates/1-start/test/widget_test.dart b/014-provider-v3-updates/1-start/test/widget_test.dart deleted file mode 100644 index 2a1e9f73..00000000 --- a/014-provider-v3-updates/1-start/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:provider_arc/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/014-provider-v3-updates/2-final/.gitignore b/014-provider-v3-updates/2-final/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/014-provider-v3-updates/2-final/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/014-provider-v3-updates/2-final/.metadata b/014-provider-v3-updates/2-final/.metadata deleted file mode 100644 index a99c5c1b..00000000 --- a/014-provider-v3-updates/2-final/.metadata +++ /dev/null @@ -1,10 +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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b - channel: stable - -project_type: app diff --git a/014-provider-v3-updates/2-final/README.md b/014-provider-v3-updates/2-final/README.md deleted file mode 100644 index 9d91bc31..00000000 --- a/014-provider-v3-updates/2-final/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# provider_arc - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/014-provider-v3-updates/2-final/lib/core/constants/app_contstants.dart b/014-provider-v3-updates/2-final/lib/core/constants/app_contstants.dart deleted file mode 100644 index 58f884e5..00000000 --- a/014-provider-v3-updates/2-final/lib/core/constants/app_contstants.dart +++ /dev/null @@ -1,9 +0,0 @@ - -// You can also just let this float around in the file without encapsulating -// in a class. Then you'll have to make sure that system wide you don't have -// duplicate variable names. -class RoutePaths { - static const String Login = 'login'; - static const String Home = '/'; - static const String Post = 'post'; -} \ No newline at end of file diff --git a/014-provider-v3-updates/2-final/lib/core/models/comment.dart b/014-provider-v3-updates/2-final/lib/core/models/comment.dart deleted file mode 100644 index 6a2ebec8..00000000 --- a/014-provider-v3-updates/2-final/lib/core/models/comment.dart +++ /dev/null @@ -1,27 +0,0 @@ -class Comment { - int postId; - int id; - String name; - String email; - String body; - - Comment({this.postId, this.id, this.name, this.email, this.body}); - - Comment.fromJson(Map json) { - postId = json['postId']; - id = json['id']; - name = json['name']; - email = json['email']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['postId'] = this.postId; - data['id'] = this.id; - data['name'] = this.name; - data['email'] = this.email; - data['body'] = this.body; - return data; - } -} \ No newline at end of file diff --git a/014-provider-v3-updates/2-final/lib/core/models/post.dart b/014-provider-v3-updates/2-final/lib/core/models/post.dart deleted file mode 100644 index c1c6cf92..00000000 --- a/014-provider-v3-updates/2-final/lib/core/models/post.dart +++ /dev/null @@ -1,24 +0,0 @@ -class Post { - int userId; - int id; - String title; - String body; - - Post({this.userId, this.id, this.title, this.body}); - - Post.fromJson(Map json) { - userId = json['userId']; - id = json['id']; - title = json['title']; - body = json['body']; - } - - Map toJson() { - final Map data = new Map(); - data['userId'] = this.userId; - data['id'] = this.id; - data['title'] = this.title; - data['body'] = this.body; - return data; - } -} \ No newline at end of file diff --git a/014-provider-v3-updates/2-final/lib/core/models/user.dart b/014-provider-v3-updates/2-final/lib/core/models/user.dart deleted file mode 100644 index 1071dc6c..00000000 --- a/014-provider-v3-updates/2-final/lib/core/models/user.dart +++ /dev/null @@ -1,25 +0,0 @@ -class User { - int id; - String name; - String username; - User({this.id, this.name, this.username}); - - User.initial() - : id = 0, - name = '', - username = ''; - - User.fromJson(Map json) { - id = json['id']; - name = json['name']; - username = json['username']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['username'] = this.username; - return data; - } -} diff --git a/014-provider-v3-updates/2-final/lib/core/services/api.dart b/014-provider-v3-updates/2-final/lib/core/services/api.dart deleted file mode 100644 index 71f1e5db..00000000 --- a/014-provider-v3-updates/2-final/lib/core/services/api.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:convert'; - -import 'package:http/http.dart' as http; -import 'package:provider_arc/core/models/comment.dart'; -import 'package:provider_arc/core/models/post.dart'; -import 'package:provider_arc/core/models/user.dart'; - -/// The service responsible for networking requests -class Api { - static const endpoint = 'https://jsonplaceholder.typicode.com'; - - var client = new http.Client(); - - Future getUserProfile(int userId) async { - // Get user profile for id - var response = await client.get('$endpoint/users/$userId'); - - // Convert and return - return User.fromJson(json.decode(response.body)); - } - - Future> getPostsForUser(int userId) async { - var posts = List(); - // Get user posts for id - var response = await client.get('$endpoint/posts?userId=$userId'); - - // parse into List - var parsed = json.decode(response.body) as List; - - // loop and convert each item to Post - for (var post in parsed) { - posts.add(Post.fromJson(post)); - } - - return posts; - } - - Future> getCommentsForPost(int postId) async { - var comments = List(); - - // Get comments for post - var response = await client.get('$endpoint/comments?postId=$postId'); - - // Parse into List - var parsed = json.decode(response.body) as List; - - // Loop and convert each item to a Comment - for (var comment in parsed) { - comments.add(Comment.fromJson(comment)); - } - - return comments; - } -} diff --git a/014-provider-v3-updates/2-final/lib/core/services/authentication_service.dart b/014-provider-v3-updates/2-final/lib/core/services/authentication_service.dart deleted file mode 100644 index 63e2ca66..00000000 --- a/014-provider-v3-updates/2-final/lib/core/services/authentication_service.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'dart:async'; - -import 'package:provider_arc/core/models/user.dart'; -import 'package:provider_arc/core/services/api.dart'; - -class AuthenticationService { - final Api _api; - - AuthenticationService({Api api}) : _api = api; - - StreamController _userController = StreamController(); - - Stream get user => _userController.stream; - - Future login(int userId) async { - var fetchedUser = await _api.getUserProfile(userId); - - var hasUser = fetchedUser != null; - if (hasUser) { - _userController.add(fetchedUser); - } - - return hasUser; - } -} diff --git a/014-provider-v3-updates/2-final/lib/core/viewmodels/base_model.dart b/014-provider-v3-updates/2-final/lib/core/viewmodels/base_model.dart deleted file mode 100644 index c1c1d6ea..00000000 --- a/014-provider-v3-updates/2-final/lib/core/viewmodels/base_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/material.dart'; - -class BaseModel extends ChangeNotifier { - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/014-provider-v3-updates/2-final/lib/core/viewmodels/views/login_view_model.dart b/014-provider-v3-updates/2-final/lib/core/viewmodels/views/login_view_model.dart deleted file mode 100644 index 42178d1c..00000000 --- a/014-provider-v3-updates/2-final/lib/core/viewmodels/views/login_view_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:provider_arc/core/services/authentication_service.dart'; -import 'package:provider_arc/core/viewmodels/base_model.dart'; - -class LoginViewModel extends BaseModel { - AuthenticationService _authenticationService; - - LoginViewModel({ - @required AuthenticationService authenticationService, - }) : _authenticationService = authenticationService; - - Future login(String userIdText) async { - setBusy(true); - var userId = int.tryParse(userIdText); - var success = await _authenticationService.login(userId); - setBusy(false); - return success; - } -} diff --git a/014-provider-v3-updates/2-final/lib/core/viewmodels/widgets/comments_model.dart b/014-provider-v3-updates/2-final/lib/core/viewmodels/widgets/comments_model.dart deleted file mode 100644 index c6f84405..00000000 --- a/014-provider-v3-updates/2-final/lib/core/viewmodels/widgets/comments_model.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:provider_arc/core/models/comment.dart'; -import 'package:provider_arc/core/services/api.dart'; -import 'package:provider_arc/core/viewmodels/base_model.dart'; - -class CommentsModel extends BaseModel { - Api _api; - - CommentsModel({ - @required Api api, - }) : _api = api; - - List comments; - - Future fetchComments(int postId) async { - setBusy(true); - comments = await _api.getCommentsForPost(postId); - setBusy(false); - } - - @override - void dispose() { - print('I have been disposed!!'); - super.dispose(); - } -} diff --git a/014-provider-v3-updates/2-final/lib/core/viewmodels/widgets/posts_model.dart b/014-provider-v3-updates/2-final/lib/core/viewmodels/widgets/posts_model.dart deleted file mode 100644 index 8a735fc4..00000000 --- a/014-provider-v3-updates/2-final/lib/core/viewmodels/widgets/posts_model.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:meta/meta.dart'; -import 'package:provider_arc/core/models/post.dart'; -import 'package:provider_arc/core/services/api.dart'; - -import '../base_model.dart'; - -class PostsModel extends BaseModel { - Api _api; - - PostsModel({ - @required Api api, - }) : _api = api; - - List posts; - - Future getPosts(int userId) async { - setBusy(true); - posts = await _api.getPostsForUser(userId); - setBusy(false); - } -} diff --git a/014-provider-v3-updates/2-final/lib/main.dart b/014-provider-v3-updates/2-final/lib/main.dart deleted file mode 100644 index 6a88a49f..00000000 --- a/014-provider-v3-updates/2-final/lib/main.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_arc/provider_setup.dart'; -import 'package:provider_arc/ui/router.dart'; - -import 'core/constants/app_contstants.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MultiProvider( - providers: providers, - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - initialRoute: RoutePaths.Login, - onGenerateRoute: Router.generateRoute, - ), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/provider_setup.dart b/014-provider-v3-updates/2-final/lib/provider_setup.dart deleted file mode 100644 index 50f38af1..00000000 --- a/014-provider-v3-updates/2-final/lib/provider_setup.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:provider/provider.dart'; -import 'package:provider/single_child_widget.dart'; -import 'package:provider_arc/core/services/authentication_service.dart'; - -import 'core/models/user.dart'; -import 'core/services/api.dart'; - -List providers = [ - ...independentServices, - ...dependentServices, - ...uiConsumableProviders -]; - -List independentServices = [Provider.value(value: Api())]; - -List dependentServices = [ - ProxyProvider( - update: (context, api, authenticationService) => - AuthenticationService(api: api), - ) -]; - -List uiConsumableProviders = [ - StreamProvider( - create: (context) => - Provider.of(context, listen: false).user, - ) -]; diff --git a/014-provider-v3-updates/2-final/lib/ui/router.dart b/014-provider-v3-updates/2-final/lib/ui/router.dart deleted file mode 100644 index cbadfebd..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/router.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider_arc/core/constants/app_contstants.dart'; -import 'package:provider_arc/core/models/post.dart'; -import 'package:provider_arc/ui/views/home_view.dart'; -import 'package:provider_arc/ui/views/login_view.dart'; -import 'package:provider_arc/ui/views/post_view.dart'; - -class Router { - static Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case RoutePaths.Home: - return MaterialPageRoute(builder: (_) => HomeView()); - case RoutePaths.Login: - return MaterialPageRoute(builder: (_) => LoginView()); - case RoutePaths.Post: - var post = settings.arguments as Post; - return MaterialPageRoute(builder: (_) => PostView(post: post)); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}'), - ), - )); - } - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/shared/app_colors.dart b/014-provider-v3-updates/2-final/lib/ui/shared/app_colors.dart deleted file mode 100644 index 43ad166d..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color backgroundColor = Color.fromARGB(255, 255, 241, 159); -const Color commentColor = Color.fromARGB(255, 255, 246, 196); diff --git a/014-provider-v3-updates/2-final/lib/ui/shared/text_styles.dart b/014-provider-v3-updates/2-final/lib/ui/shared/text_styles.dart deleted file mode 100644 index 86fec3eb..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/shared/text_styles.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:flutter/material.dart'; - -const headerStyle = TextStyle(fontSize: 35, fontWeight: FontWeight.w900); -const subHeaderStyle = TextStyle(fontSize: 16.0, fontWeight: FontWeight.w500); \ No newline at end of file diff --git a/014-provider-v3-updates/2-final/lib/ui/shared/ui_helpers.dart b/014-provider-v3-updates/2-final/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 29cfb895..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -/// Contains useful consts to reduce boilerplate and duplicate code -class UIHelper { - // Vertical spacing constants. Adjust to your liking. - static const double _VerticalSpaceSmall = 10.0; - static const double _VerticalSpaceMedium = 20.0; - static const double _VerticalSpaceLarge = 60.0; - - // Vertical spacing constants. Adjust to your liking. - static const double _HorizontalSpaceSmall = 10.0; - static const double _HorizontalSpaceMedium = 20.0; - static const double _HorizontalSpaceLarge = 60.0; - - static const Widget verticalSpaceSmall = SizedBox(height: _VerticalSpaceSmall); - static const Widget verticalSpaceMedium = SizedBox(height: _VerticalSpaceMedium); - static const Widget verticalSpaceLarge = SizedBox(height: _VerticalSpaceLarge); - - static const Widget horizontalSpaceSmall = SizedBox(width: _HorizontalSpaceSmall); - static const Widget horizontalSpaceMedium = SizedBox(width: _HorizontalSpaceMedium); - static const Widget horizontalSpaceLarge = SizedBox(width: _HorizontalSpaceLarge); -} diff --git a/014-provider-v3-updates/2-final/lib/ui/views/base_widget.dart b/014-provider-v3-updates/2-final/lib/ui/views/base_widget.dart deleted file mode 100644 index 246b5fec..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/views/base_widget.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class BaseWidget extends StatefulWidget { - final Widget Function(BuildContext context, T model, Widget child) builder; - final T model; - final Widget child; - final Function(T) onModelReady; - - BaseWidget({ - Key key, - this.builder, - this.model, - this.child, - this.onModelReady, - }) : super(key: key); - - _BaseWidgetState createState() => _BaseWidgetState(); -} - -class _BaseWidgetState extends State> { - T model; - - @override - void initState() { - model = widget.model; - - if (widget.onModelReady != null) { - widget.onModelReady(model); - } - - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => model, - child: Consumer( - builder: widget.builder, - child: widget.child, - ), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/views/home_view.dart b/014-provider-v3-updates/2-final/lib/ui/views/home_view.dart deleted file mode 100644 index fb3c3640..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/views/home_view.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_arc/core/models/user.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; -import 'package:provider_arc/ui/shared/text_styles.dart'; -import 'package:provider_arc/ui/shared/ui_helpers.dart'; -import 'package:provider_arc/ui/widgets/posts.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge, - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text( - 'Welcome ${Provider.of(context).name}', - style: headerStyle, - ), - ), - Padding( - padding: const EdgeInsets.only(left: 20.0), - child: Text('Here are all your posts', style: subHeaderStyle), - ), - UIHelper.verticalSpaceSmall, - Expanded(child: Posts(),) - ], - ), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/views/login_view.dart b/014-provider-v3-updates/2-final/lib/ui/views/login_view.dart deleted file mode 100644 index 95670eb9..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/views/login_view.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_arc/core/constants/app_contstants.dart'; -import 'package:provider_arc/core/viewmodels/views/login_view_model.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; -import 'package:provider_arc/ui/widgets/login_header.dart'; - -import 'base_widget.dart'; - -class LoginView extends StatefulWidget { - @override - _LoginViewState createState() => _LoginViewState(); -} - -class _LoginViewState extends State { - final TextEditingController _controller = TextEditingController(); - - @override - Widget build(BuildContext context) { - return BaseWidget( - model: LoginViewModel(authenticationService: Provider.of(context)), - child: LoginHeader(controller: _controller), - builder: (context, model, child) => Scaffold( - backgroundColor: backgroundColor, - body: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - child, - model.busy - ? CircularProgressIndicator() - : FlatButton( - color: Colors.white, - child: Text( - 'Login', - style: TextStyle(color: Colors.black), - ), - onPressed: () async { - var loginSuccess = await model.login(_controller.text); - if (loginSuccess) { - Navigator.pushNamed(context, RoutePaths.Home); - } - }, - ) - ], - )), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/views/post_view.dart b/014-provider-v3-updates/2-final/lib/ui/views/post_view.dart deleted file mode 100644 index abaec596..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/views/post_view.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_arc/core/models/post.dart'; -import 'package:provider_arc/core/models/user.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; -import 'package:provider_arc/ui/shared/text_styles.dart'; -import 'package:provider_arc/ui/shared/ui_helpers.dart'; -import 'package:provider_arc/ui/widgets/comments.dart'; - -class PostView extends StatelessWidget { - final Post post; - const PostView({Key key, this.post}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: backgroundColor, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 20.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - UIHelper.verticalSpaceLarge, - Text(post.title, style: headerStyle), - Text( - 'by ${Provider.of(context).name}', - style: TextStyle(fontSize: 9.0), - ), - UIHelper.verticalSpaceMedium, - Text(post.body), - Comments(post.id) - ], - ), - ), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/widgets/comments.dart b/014-provider-v3-updates/2-final/lib/ui/widgets/comments.dart deleted file mode 100644 index 2578158e..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/widgets/comments.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_arc/core/models/comment.dart'; -import 'package:provider_arc/core/viewmodels/widgets/comments_model.dart'; -import 'package:provider_arc/ui/shared/app_colors.dart'; -import 'package:provider_arc/ui/shared/ui_helpers.dart'; -import 'package:provider_arc/ui/views/base_widget.dart'; - -class Comments extends StatelessWidget { - final int postId; - Comments(this.postId); - - @override - Widget build(BuildContext context) { - return BaseWidget( - onModelReady: (model) => model.fetchComments(postId), - model: CommentsModel(api: Provider.of(context)), - builder: (context, model, child) => model.busy - ? Center( - child: CircularProgressIndicator(), - ) - : Expanded( - child: ListView.builder( - itemCount: model.comments.length, - itemBuilder: (context, index) => - CommentItem(model.comments[index]), - ), - )); - } -} - -/// Renders a single comment given a comment model -class CommentItem extends StatelessWidget { - final Comment comment; - const CommentItem(this.comment); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.all(10.0), - margin: EdgeInsets.symmetric(vertical: 10.0), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.0), color: commentColor), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - comment.name, - style: TextStyle(fontWeight: FontWeight.bold), - ), - UIHelper.verticalSpaceSmall, - Text(comment.body), - ], - ), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/widgets/login_header.dart b/014-provider-v3-updates/2-final/lib/ui/widgets/login_header.dart deleted file mode 100644 index 825e58d9..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/widgets/login_header.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/ui/shared/text_styles.dart'; -import 'package:provider_arc/ui/shared/ui_helpers.dart'; - -class LoginHeader extends StatelessWidget { - final TextEditingController controller; - final String validationMessage; - - LoginHeader({@required this.controller, this.validationMessage}); - - @override - Widget build(BuildContext context) { - return Column(children: [ - Text('Login', style: headerStyle), - UIHelper.verticalSpaceMedium, - Text('Enter a number between 1 - 10', style: subHeaderStyle), - LoginTextField(controller), - this.validationMessage != null - ? Text(validationMessage, style: TextStyle(color: Colors.red)) - : Container() - ]); - } -} - -class LoginTextField extends StatelessWidget { - final TextEditingController controller; - - LoginTextField(this.controller); - - @override - Widget build(BuildContext context) { - return Container( - padding: EdgeInsets.symmetric(horizontal: 15.0), - margin: EdgeInsets.symmetric(horizontal: 15.0, vertical: 15.0), - height: 50.0, - alignment: Alignment.centerLeft, - decoration: BoxDecoration( - color: Colors.white, borderRadius: BorderRadius.circular(10.0)), - child: TextField( - decoration: InputDecoration.collapsed(hintText: 'User Id'), - controller: controller), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/widgets/postlist_item.dart b/014-provider-v3-updates/2-final/lib/ui/widgets/postlist_item.dart deleted file mode 100644 index 7318c4c4..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/widgets/postlist_item.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider_arc/core/models/post.dart'; - -class PostListItem extends StatelessWidget { - final Post post; - final Function onTap; - const PostListItem({this.post, this.onTap}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTap, - child: Container( - margin: EdgeInsets.symmetric(horizontal: 20.0, vertical: 15.0), - padding: EdgeInsets.all(10.0), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5.0), - boxShadow: [ - BoxShadow( - blurRadius: 3.0, - offset: Offset(0.0, 2.0), - color: Color.fromARGB(80, 0, 0, 0)) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(post.title, style: TextStyle(fontWeight: FontWeight.w900, fontSize: 16.0),), - Text(post.body, maxLines: 2, overflow: TextOverflow.ellipsis) - ], - ), - ), - ); - } -} diff --git a/014-provider-v3-updates/2-final/lib/ui/widgets/posts.dart b/014-provider-v3-updates/2-final/lib/ui/widgets/posts.dart deleted file mode 100644 index 00733ab4..00000000 --- a/014-provider-v3-updates/2-final/lib/ui/widgets/posts.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:provider_arc/core/constants/app_contstants.dart'; -import 'package:provider_arc/core/models/user.dart'; -import 'package:provider_arc/core/viewmodels/widgets/posts_model.dart'; -import 'package:provider_arc/ui/views/base_widget.dart'; -import 'package:provider_arc/ui/widgets/postlist_item.dart'; - -class Posts extends StatelessWidget { - const Posts({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BaseWidget( - model: PostsModel(api: Provider.of(context)), - onModelReady: (model) => model.getPosts(Provider.of(context).id), - builder: (context, model, child) => model.busy - ? Center( - child: CircularProgressIndicator(), - ) - : ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => PostListItem( - post: model.posts[index], - onTap: () { - Navigator.pushNamed( - context, - RoutePaths.Post, - arguments: model.posts[index], - ); - }, - ), - )); - } -} diff --git a/014-provider-v3-updates/2-final/pubspec.lock b/014-provider-v3-updates/2-final/pubspec.lock deleted file mode 100644 index 18395bab..00000000 --- a/014-provider-v3-updates/2-final/pubspec.lock +++ /dev/null @@ -1,182 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/014-provider-v3-updates/2-final/pubspec.yaml b/014-provider-v3-updates/2-final/pubspec.yaml deleted file mode 100644 index a0e1333b..00000000 --- a/014-provider-v3-updates/2-final/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: provider_arc -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - http: ^0.12.1 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/014-provider-v3-updates/2-final/test/widget_test.dart b/014-provider-v3-updates/2-final/test/widget_test.dart deleted file mode 100644 index 2a1e9f73..00000000 --- a/014-provider-v3-updates/2-final/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:provider_arc/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/015-flare-splashscreen/flare_splash/.gitignore b/015-flare-splashscreen/flare_splash/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/015-flare-splashscreen/flare_splash/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/015-flare-splashscreen/flare_splash/.metadata b/015-flare-splashscreen/flare_splash/.metadata deleted file mode 100644 index a99c5c1b..00000000 --- a/015-flare-splashscreen/flare_splash/.metadata +++ /dev/null @@ -1,10 +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: 7a4c33425ddd78c54aba07d86f3f9a4a0051769b - channel: stable - -project_type: app diff --git a/015-flare-splashscreen/flare_splash/README.md b/015-flare-splashscreen/flare_splash/README.md deleted file mode 100644 index 3173df65..00000000 --- a/015-flare-splashscreen/flare_splash/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# flare_splash - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/015-flare-splashscreen/flare_splash/assets/splash.flr b/015-flare-splashscreen/flare_splash/assets/splash.flr deleted file mode 100644 index 3f6b1248..00000000 --- a/015-flare-splashscreen/flare_splash/assets/splash.flr +++ /dev/null @@ -1,1430 +0,0 @@ -{ - "version": 21, - "artboards": [ - { - "name": "splash", - "translation": [ - 0, - 0 - ], - "width": 288, - "height": 512, - "origin": [ - 0, - 0 - ], - "clipContents": true, - "color": [ - 0.0941176488995552, - 0.0941176488995552, - 0.0941176488995552, - 1 - ], - "nodes": [ - { - "name": "filledstacks", - "translation": [ - 144, - 256 - ], - "rotation": 0, - "scale": [ - 0.20434705913066864, - 0.20434705913066864 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "isVisible": true, - "blendMode": 3, - "drawOrder": 8, - "bones": [], - "atlas": 0, - "numVertices": 4, - "vertices": [ - -620, - -236, - 0.00048828125, - 0.38134765625, - 620, - -236, - 0.00048828125, - 0.98681640625, - 620, - 236, - 0.23095703125, - 0.98681640625, - -620, - 236, - 0.23095703125, - 0.38134765625 - ], - "numTriangles": 2, - "triangles": [ - 3, - 0, - 1, - 1, - 2, - 3 - ], - "type": "image" - }, - { - "name": "bettercode", - "translation": [ - 142.69500732421875, - 312.3175048828125 - ], - "rotation": 0, - "scale": [ - 0.20000000298023224, - 0.20000000298023224 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "isVisible": true, - "blendMode": 3, - "drawOrder": 7, - "bones": [], - "atlas": 0, - "numVertices": 4, - "vertices": [ - -258, - -68, - 0.24267578125, - 0.00048828125, - 258, - -68, - 0.49462890625, - 0.00048828125, - 258, - 68, - 0.49462890625, - 0.06689453125, - -258, - 68, - 0.24267578125, - 0.06689453125 - ], - "numTriangles": 2, - "triangles": [ - 3, - 0, - 1, - 1, - 2, - 3 - ], - "type": "image" - }, - { - "name": "codeprinciples", - "translation": [ - 145.49874877929688, - 347.36407470703125 - ], - "rotation": 0, - "scale": [ - 0.20000000298023224, - 0.20000000298023224 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "isVisible": true, - "blendMode": 3, - "drawOrder": 4, - "bones": [], - "atlas": 0, - "numVertices": 4, - "vertices": [ - -322, - -66, - 0.08447265625, - 0.06591796875, - 322, - -66, - 0.08447265625, - 0.38037109375, - 322, - 66, - 0.14892578125, - 0.38037109375, - -322, - 66, - 0.14892578125, - 0.06591796875 - ], - "numTriangles": 2, - "triangles": [ - 3, - 0, - 1, - 1, - 2, - 3 - ], - "type": "image" - }, - { - "name": "production", - "translation": [ - 144.0968780517578, - 390.822021484375 - ], - "rotation": 0, - "scale": [ - 0.20000000298023224, - 0.20000000298023224 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "isVisible": true, - "blendMode": 3, - "drawOrder": 5, - "bones": [], - "atlas": 0, - "numVertices": 4, - "vertices": [ - -248, - -85, - 0.00048828125, - 0.06591796875, - 248, - -85, - 0.00048828125, - 0.30810546875, - 248, - 85, - 0.08349609375, - 0.30810546875, - -248, - 85, - 0.08349609375, - 0.06591796875 - ], - "numTriangles": 2, - "triangles": [ - 3, - 0, - 1, - 1, - 2, - 3 - ], - "type": "image" - }, - { - "name": "architecture", - "translation": [ - 146.900634765625, - 432.8780822753906 - ], - "rotation": 0, - "scale": [ - 0.20000000298023224, - 0.20000000298023224 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "isVisible": true, - "blendMode": 3, - "drawOrder": 6, - "bones": [], - "atlas": 0, - "numVertices": 4, - "vertices": [ - -247, - -66, - 0.00048828125, - 0.00048828125, - 247, - -66, - 0.24169921875, - 0.00048828125, - 247, - 66, - 0.24169921875, - 0.06494140625, - -247, - 66, - 0.00048828125, - 0.06494140625 - ], - "numTriangles": 2, - "triangles": [ - 3, - 0, - 1, - 1, - 2, - 3 - ], - "type": "image" - }, - { - "name": "lines", - "translation": [ - -7.9944353103637695, - 179.41555786132812 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "isVisible": true, - "blendMode": 3, - "drawOrder": 3, - "type": "shape" - }, - { - "name": "Path", - "parent": 5, - "translation": [ - 0, - 0 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "bones": [], - "isVisible": true, - "isClosed": false, - "points": [ - { - "pointType": 0, - "translation": [ - 0, - 0 - ], - "radius": 0 - }, - { - "pointType": 1, - "translation": [ - 321.028076171875, - -135.98129272460938 - ], - "in": [ - 151.40203857421875, - -9.813064575195312 - ], - "out": [ - 490.6542053222656, - -262.14971923828125 - ] - } - ], - "type": "path" - }, - { - "name": "Path", - "parent": 5, - "translation": [ - 0, - 0 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "bones": [], - "isVisible": true, - "isClosed": false, - "points": [ - { - "pointType": 0, - "translation": [ - -4.205608367919922, - 120.56074523925781 - ], - "radius": 0 - }, - { - "pointType": 1, - "translation": [ - 332.2430114746094, - 318.22430419921875 - ], - "in": [ - 307.0094299316406, - 110.7476806640625 - ], - "out": [ - 357.4765930175781, - 525.700927734375 - ] - } - ], - "type": "path" - }, - { - "name": "Path", - "parent": 5, - "translation": [ - 0, - 0 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "bones": [], - "isVisible": true, - "isClosed": false, - "points": [ - { - "pointType": 0, - "translation": [ - -5.607477188110352, - 192.0560760498047 - ], - "radius": 0 - }, - { - "pointType": 1, - "translation": [ - 228.50466918945312, - 329.43927001953125 - ], - "in": [ - 206.074951171875, - 194.85980224609375 - ], - "out": [ - 250.93438720703125, - 464.01873779296875 - ] - } - ], - "type": "path" - }, - { - "name": "Path", - "parent": 5, - "translation": [ - 0, - 0 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "bones": [], - "isVisible": true, - "isClosed": false, - "points": [ - { - "pointType": 0, - "translation": [ - -9.81308364868164, - 65.88786315917969 - ], - "radius": 0 - }, - { - "pointType": 0, - "translation": [ - 473.831787109375, - 33.64485168457031 - ], - "radius": 0 - } - ], - "type": "path" - }, - { - "name": "Path", - "parent": 5, - "translation": [ - 0, - 0 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "bones": [], - "isVisible": true, - "isClosed": false, - "points": [ - { - "pointType": 0, - "translation": [ - 301.4018859863281, - 50.46730041503906 - ], - "radius": 0 - } - ], - "type": "path" - }, - { - "name": "Path", - "parent": 5, - "translation": [ - 0, - 0 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "bones": [], - "isVisible": true, - "isClosed": false, - "points": [ - { - "pointType": 0, - "translation": [ - 850.9345703125, - 344.85980224609375 - ], - "radius": 0 - }, - { - "pointType": 0, - "translation": [ - 828.5046997070312, - 271.962646484375 - ], - "radius": 0 - } - ], - "type": "path" - }, - { - "name": "Path", - "parent": 5, - "translation": [ - 0, - 0 - ], - "rotation": 0, - "scale": [ - 1, - 1 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "bones": [], - "isVisible": true, - "isClosed": false, - "points": [ - { - "pointType": 0, - "translation": [ - 810.2803955078125, - 14.018692016601562 - ], - "radius": 0 - } - ], - "type": "path" - }, - { - "name": "Color", - "parent": 5, - "opacity": 0.1, - "color": [ - 1, - 1, - 1, - 1 - ], - "width": 15, - "cap": 1, - "join": 0, - "trim": 2, - "start": 0, - "end": 1, - "offset": 0, - "type": "colorStroke" - }, - { - "name": "mobilephone", - "translation": [ - 144, - 256 - ], - "rotation": 0, - "scale": [ - 0.20000000298023224, - 0.20000000298023224 - ], - "opacity": 1, - "isCollapsed": false, - "clips": [], - "isVisible": true, - "blendMode": 3, - "drawOrder": 9, - "bones": [], - "atlas": 0, - "numVertices": 4, - "vertices": [ - -323, - -513, - 0.49560546875, - 0.00048828125, - 323, - -513, - 0.49560546875, - 0.31591796875, - 323, - 513, - 0.99658203125, - 0.31591796875, - -323, - 513, - 0.99658203125, - 0.00048828125 - ], - "numTriangles": 2, - "triangles": [ - 3, - 0, - 1, - 1, - 2, - 3 - ], - "type": "image" - } - ], - "animations": [ - { - "name": "intro", - "fps": 60, - "duration": 2.5, - "isLooping": false, - "keyed": [ - { - "component": 0, - "scaleX": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 0.20434705913066864 - }, - { - "time": 0.4166666666666667, - "interpolatorType": 1, - "value": 0.21 - }, - { - "time": 0.5, - "interpolatorType": 1, - "value": 0.25 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 2, - "interpolatorType": 2, - "cubicX1": 0, - "cubicY1": 1.9583333333333333, - "cubicX2": 0.3225806451612903, - "cubicY2": 0.7688172043010753, - "value": 0 - }, - { - "time": 2.1666666666666665, - "interpolatorType": 1, - "value": 0.2 - } - ] - ], - "scaleY": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 0.20434705913066864 - }, - { - "time": 0.4166666666666667, - "interpolatorType": 1, - "value": 0.21 - }, - { - "time": 0.5, - "interpolatorType": 1, - "value": 0.25 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 2, - "interpolatorType": 2, - "cubicX1": 0, - "cubicY1": 1.9583333333333333, - "cubicX2": 0.3225806451612903, - "cubicY2": 0.7688172043010753, - "value": 0 - }, - { - "time": 2.1666666666666665, - "interpolatorType": 1, - "value": 0.2 - } - ] - ] - }, - { - "component": 1, - "posY": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 263.2520751953125 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 263.2520751953125 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.005376344086021506, - "cubicY1": 0.6881720430107527, - "cubicX2": 0.58, - "cubicY2": 1, - "value": 295.21929931640625 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 307.5143737792969 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 314.89141845703125 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 263.2520751953125 - } - ] - ], - "posX": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 141.2931365966797 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 141.2931365966797 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.005376344086021506, - "cubicY1": 0.6881720430107527, - "cubicX2": 0.58, - "cubicY2": 1, - "value": 210.1455841064453 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 221.21115112304688 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 228.58819580078125 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 141.2931365966797 - } - ] - ], - "rotation": [ - [ - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.005376344086021506, - "cubicY1": 0.6881720430107527, - "cubicX2": 0.58, - "cubicY2": 1, - "value": -0.5462880558742249 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": -0.8220500776893291 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": -0.9756390518648301 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0 - } - ] - ] - }, - { - "component": 2, - "posX": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 144.0968780517578 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 144.0968780517578 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.026881720430107527, - "cubicY1": 0.7620967741935484, - "cubicX2": 0.478494623655914, - "cubicY2": 1.010752688172043, - "value": 88.76901245117188 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 76.47393035888672 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 71.55587005615234 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 144.0968780517578 - } - ] - ], - "posY": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 257.64447021484375 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 257.64447021484375 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.026881720430107527, - "cubicY1": 0.7620967741935484, - "cubicX2": 0.478494623655914, - "cubicY2": 1.010752688172043, - "value": 342.48052978515625 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 358.4641418457031 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 368.3002014160156 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 257.64447021484375 - } - ] - ], - "rotation": [ - [ - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.026881720430107527, - "cubicY1": 0.7620967741935484, - "cubicX2": 0.478494623655914, - "cubicY2": 1.010752688172043, - "value": 0.44854961776254293 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 0.49218284906240095 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 0.588175957922089 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0 - } - ] - ] - }, - { - "component": 3, - "posX": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 145.49874877929688 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 145.49874877929688 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.043010752688172046, - "cubicY1": 0.7016129032258065, - "cubicX2": 0.58, - "cubicY2": 1, - "value": 216.81021118164062 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 241.40037536621094 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 243.8594207763672 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 145.49874877929688 - } - ] - ], - "posY": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 259.04632568359375 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 259.04632568359375 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.043010752688172046, - "cubicY1": 0.7016129032258065, - "cubicX2": 0.58, - "cubicY2": 1, - "value": 193.88238525390625 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 171.75123596191406 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 165.6037139892578 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 259.04632568359375 - } - ] - ], - "rotation": [ - [ - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.043010752688172046, - "cubicY1": 0.7016129032258065, - "cubicX2": 0.58, - "cubicY2": 1, - "value": 0.41189770347066207 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 0.5235987755982988 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 0.6021385919380438 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0 - } - ] - ] - }, - { - "component": 4, - "posX": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 148.302490234375 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 148.302490234375 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.005376344086021506, - "cubicY1": 1.0577956989247312, - "cubicX2": 0.43548387096774194, - "cubicY2": 0.8763440860215054, - "value": 78.22052001953125 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 68.38445281982422 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 67.15496063232422 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 148.302490234375 - } - ] - ], - "posY": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 257.6444091796875 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 257.6444091796875 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.005376344086021506, - "cubicY1": 1.0577956989247312, - "cubicX2": 0.43548387096774194, - "cubicY2": 0.8763440860215054, - "value": 181.41490173339844 - }, - { - "time": 1, - "interpolatorType": 2, - "cubicX1": 0.7365591397849462, - "cubicY1": -0.004032258064516014, - "cubicX2": 1, - "cubicY2": 0.37231182795698925, - "value": 174.037841796875 - }, - { - "time": 1.25, - "interpolatorType": 1, - "value": 171.57882690429688 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 257.6444091796875 - } - ] - ], - "rotation": [ - [ - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 0.6666666666666666, - "interpolatorType": 2, - "cubicX1": 0.005376344086021506, - "cubicY1": 1.0577956989247312, - "cubicX2": 0.43548387096774194, - "cubicY2": 0.8763440860215054, - "value": -0.6457718232379024 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0 - } - ] - ] - }, - { - "component": 5 - }, - { - "component": 13, - "strokeEnd": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 0.16666666666666666, - "interpolatorType": 1, - "value": 1 - }, - { - "time": 0.4166666666666667, - "interpolatorType": 1, - "value": 0.25499999999999956 - }, - { - "time": 0.5833333333333334, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0 - } - ] - ], - "strokeStart": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 0.16666666666666666, - "interpolatorType": 1, - "value": 0.5799999999999998 - }, - { - "time": 0.25, - "interpolatorType": 1, - "value": 1 - }, - { - "time": 0.4166666666666667, - "interpolatorType": 1, - "value": 0 - } - ] - ] - }, - { - "component": 14, - "scaleX": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 1.3333333333333333, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0.25 - }, - { - "time": 1.75, - "interpolatorType": 1, - "value": 0.25 - }, - { - "time": 1.9166666666666667, - "interpolatorType": 1, - "value": 0.26 - }, - { - "time": 2, - "interpolatorType": 1, - "value": 0.275 - }, - { - "time": 2.1666666666666665, - "interpolatorType": 1, - "value": 0 - } - ] - ], - "scaleY": [ - [ - { - "time": 0, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 1.3333333333333333, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0.25 - }, - { - "time": 1.75, - "interpolatorType": 1, - "value": 0.25 - }, - { - "time": 1.9166666666666667, - "interpolatorType": 1, - "value": 0.26 - }, - { - "time": 2, - "interpolatorType": 1, - "value": 0.275 - }, - { - "time": 2.1666666666666665, - "interpolatorType": 1, - "value": 0 - } - ] - ], - "posY": [ - [ - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 262.1475830078125 - } - ] - ], - "posX": [ - [ - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 152.6065673828125 - } - ] - ], - "rotation": [ - [ - { - "time": 1.4333333333333333, - "interpolatorType": 1, - "value": 0 - }, - { - "time": 1.5, - "interpolatorType": 1, - "value": -0.11170107212763707 - }, - { - "time": 1.5833333333333333, - "interpolatorType": 1, - "value": 0.0994837673636769 - }, - { - "time": 1.6666666666666667, - "interpolatorType": 1, - "value": -0.12566370614359165 - }, - { - "time": 1.75, - "interpolatorType": 1, - "value": 0 - } - ] - ] - }, - { - "component": 0, - "drawOrder": [ - [ - { - "time": 0, - "drawOrder": [ - { - "component": 0, - "order": 6 - }, - { - "component": 1, - "order": 1 - }, - { - "component": 2, - "order": 3 - }, - { - "component": 3, - "order": 4 - }, - { - "component": 4, - "order": 5 - } - ] - } - ] - ] - } - ], - "animationStart": 0, - "animationEnd": 2.1666666666666665, - "type": "animation" - } - ], - "type": "artboard" - } - ], - "atlases": { - "isOOB": false, - "data": [ - "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAACAAAAAgACAYAAACyp9MwAAAgAElEQVR4XuydB5gUxdaGz+6ywJIkI0FAVLIoChgARb0owlVEMV0DBqI5oaiIYhYTBkCu4I8JAwYQREQQBUUuQQRRdEXJObO7bJ7+n9NuY9PboarT9Mx+9bDPDjOnqk69VdM70+erUylERIqiKPwbBQRAAARAAARAIPIEHklJSRkZgJcphjaN/7fqUtQuAJfRJAiAAAiAAAjEnYDId2mjjUiduA8MDiQ9AXyGS/opxgBBAARAAARAAARAAAQSlAC+MyboxEXJ7RQE/6M0HfAFBEAABEAABBwJPMIWAYgAIABwRA8DEAABEAABEChFQOTGDAQAWDhRJAABQBRnBT6BAAiAAAiAAAiAAAiAAJHI90xwAgFbAhAAYIGAAAiAAAiAQGIR8FMAoN341d8ANnuMG8SJtUbgLQiAAAiAQPwJ6G/YaI/NnmNPcXMn/vOVbB7gs1uyzSjGAwIgAAIgAAIgAAIgAAKHE8D3SKwICACwBkAABEAABEAgiQh4FQBYBf31z/Njo53ZjWTcXE6ihYWhgAAIgAAIuCZgduNFH/Tnx8b/6wP/ZgIB186gYtIQCPtzVtj9Jc1EYSAgAAIgAAIgAAIgAAIg4JFA2MH8sPvziAfV3RBABgA31FAHBEAABEAABOJHwK0AwCqgrwX7U0uC/tr/jb95xG6PCYgfLfQMAiAAAiAAAsETMEvxbyYAiJUIATRBgP43ewkhQPBzFbUe/Ay6+9lW1DjBHxAAARAAARAAARAAARAAAWsCfgf0/W4PcxcHAhAAxAE6ugQBEAABEAABDwTcCACMu/u5e33Anx+rPzVr1kyZN29ehyZNmvQsX75883LlytVLS0s7MjU1tR4RVfDgN6qCAAiAAAiAQJkgoCjKnuLi4m38E4vFtuzbt+/7adOmzRoyZMjukiA/CwE0MYBRFMCMIARIvpXiR3DejzbckI1Xv258RR0QAAEQAAEQAAEQAAEQiDKBeAXW/ejXjzaiPDdJ5xsEAEk3pRgQCIAACIBAkhOQFQAY0/nz/7XgP/9O4/8vWrSoXdu2bW/MyMg4vyTYn+QYMTwQAAEQAAEQCJVAcX5+/qL9+/d/esstt7w1ZcqUvBIRQLFOFGDMDKAXA4TqLDrzRMBLwNxLXSeng2zbqW+8DgIgAAIgAAIgAAIgAAIg4J5AkMF3L217qeueBmoKEYAAQAgTjEAABEAABEAgMgREBQDGXf/6VP+HAv8ffvhhk549ez5YuXLlS0uEAZEZKBwBARAAARAAgWQkEIvFNm7evPnJdu3avb9v3z4WAPCPlhVAnxGAh6+JApIRRbKMyW1g3W09M25+tmU1L2H0kSxrAuMAARAAARAAARAAARAAAT2BMALlfvbhti239bBaAiAAAUAAUNEkCIAACIAACARIQEQAYBb8P5Tmn4jKNWrUqNyKFSuG1axZ8zak9g9wttA0CIAACIAACFgQKCwsXLVgwYJB55xzzi8lIgAzIQDXhgggeqvITTDcTR39yL3U91LXiX6QbTv1jddBAARAAARAAARAAARAIGoEggyCu23bbT2Nrdv6butFbU4T0h8IABJy2uA0CIAACIBAGSYgKgDQdvxrKf851b/6c/PNN1cfNWrU+EqVKp1Xhjli6CAAAiAAAiAQdwKKomSvXr16cJs2bWYSUZGJEEC7YQIRQNxni2QD3bL2+hG6qeumjtanl7rxnxl4AAIgAAIgAAIgAAIgAALJQcBLwFy2rqy9nrCbum7qJMesxmkUEADECTy6BQEQAAEQAAGXBJwEAPrAvzH4X+7tt99udvnll7+bnp7e0mX/qAYCIAACIAACIOAvgdi2bdueqF+//ktEVKgTAmjHAkAE4C9vmdZkA+Oy9povMvVkbLl9WXsnPn6359QfXgcBEAABEAABEAABEACBRCXgd9Bbtr2g7bV5CaufRF0HcfEbAoC4YEenIAACIAACIOCagJ0AwC74nz506NDaTzzxxJfp6elHu+4dFUEABEAABEAABAIhsHHjxgcbN278X50IgDMC6EUAeiFAID6gUZWAbIBb1l6mD5G2RWz0Uytrb7cs/GwLyw8EQAAEQAAEQAAEQAAEkoGAbDDcacwy7Yna+m2nH4No21odWXsnXni9hAAEAFgKIAACIAACIJBYBKwEAFrwn0eTWvKjpf1Pb9KkScXVq1d/kJGR0TWxhgtvQQAEQAAEQKDMEChatGjRVaeddtrXJSIAzgZQbCICwA0S/5eEbCA7CHuRNp1snF7Xk5OxFSHud3sifcIGBEAABEAABEAABEAABKJCwM/vaTJtidg62Ti9zoxFbIxzIVNHxjYqcx5pPyAAiPT0wDkQAAEQAAEQKEXASQCgT/tfjojS+WfXrl1P1apV6wbwBAEQAAEQAAEQiC6BWCy2f9KkSeffeOONmSaZAPiGiP4nugNJHM9kgtYpK1asyGjWrFnTjIyMJikpKZxR6Ugiqp2SklKr5HdNIjqCiCoQUXndb36MAgIgAAIgAAIgAAIgAAIgEBwBzqBWoChKAf8u+cmJxWJ7FEXZzT+xWGx3UVHRroKCgg1ZWVnrfvnll/U9e/bc7cElv4PWMu052dq97qWuhsupDSNWUXtROw/TVjaqQgBQNuYZowQBEAABEEgeAmYCAGPqf975fyj4P2PGjE69evWa7iKlbfJQw0hAAARAAARAIEEIZGdnf121atWriShfJwIwywSQICOKpJu2gf89e/ZUq1q16vGpqanHE1G71NTUtkR0HBHVi+Ro4BQIgAAIgAAIgAAIgAAIgIBbAtmxWGx9LBb7taCgYFVubu7Pa9asWXXqqaductugRD3ZYLeTvdvX3dbThupUX48kKFsJ7GXDFAKAsjHPGCUIgAAIgEDyELATAOhT//POf3XnWU5OzkeVKlU6NXkQYCQgAAIgAAIgkNwE5syZc3n37t2/Ldm1wkcB8G4WTQSALADupt806P/II4+k3H///W3KlSvXJTU19XQi4p9m7rpALRAAARAAARAAARAAARAAgWQgoCjK/uLi4iV5eXmL9u3b98PEiROXPvLIIzm6sckEsp2QiLbldle/VT2/ntfGJzoOtg/K1ol1mXkdAoAyM9UYKAiAAAiAQJIQMAoA9Lv/WQCg7f5Xg/8LFizo0aVLlzeSZOwYBgiAAAiAAAiUCQK5ubkrKlWqdAER5RlEADEi4h9NBFAmePgwyMOC/3l5ecekp6efn5qaeh4RdSai6j70gSZAAARAAARAAARAAARAAASSl0BRLBZbmZubO2/Hjh2zb7jhhsXffPMNi7X9KiIBcTcCALM6MoF/N30yE5HxaOxEbUXt/JqThG4HAoCEnj44DwIgAAIgUAYJWAkAtN3/Wup/Pnu2YnZ29ieVK1c+uQxywpBBAARAAARAIKEJzJ49++rzzjtvnk4EYMwCwEIAFHsCauD/ww8/TO3Tp8/Z5cqVY1FFj5J0/mAHAiAAAiAAAiAAAiAAAiAAAq4IKIpyoLCwcF5WVtbsKVOmTBsyZMh+Vw39U0kkuC0TuOeWRYP/Xuys+tFGJjIuWVuZNj1OS+JWhwAgcecOnoMACIAACJRNAmYCAH3qfxYAcPC/wk033dRwzJgxi4iIX0cBARAAARAAARBIIAJbt259p0GDBg+WCADyiUg7CgBZAJznUQ385+fntylfvvw1RHQVETV0rgYLEAABEAABEAABEAABEAABEJAmkJ+fnz9rx44d711//fVz5s6da8wMIBOwdrIVDdbzIIy2onXd1jPrUw/TaWyard920hOaDBUgAEiGWcQYQAAEQAAEyhIBowCAg/t8k1tL/Z9eIgDIWLZs2dUnnXTS42UJDsYKAiAAAiAAAslCoKCgYFuFChW6EFGuIQsAZwLAMQDmE52SnZ1dNyMj4z+pqakc+G+fLOsB4wABEAABEAABEAABEAABEIg+AUVRduXm5n6cmZn5fvv27ZfrPBYNanMV2bT7fgX2RdoRsdGGLZuxwDjBosxE7aK/gHz0EAIAH2GiKRAAARAAARAIgYAmAHi0pC8O/rMIgAUAHPwvz6n/iShjz549E2rUqNEtBJ/QBQiAAAiAAAiAQAAEJkyYcMmAAQOWlogAjFkA+CYHjgEgoo0bN2bUr1+/d1paGgf9zyUizoiEAgIgAAIgAAIgAAIgAAIgAAJxI1BUVJSZnZ39/ty5cz/s27fvZhNHnALXMgF0kcC8085+r6/zEEX80FA4jV/GTrStuK2HsDuGACBs4ugPBEAABEAABLwRMAoA9On/OfjPPxlEVKmgoGBBenp6HW/doTYIgAAIgAAIgEC8CCxevHjkKaec8hYRHeSM9kRUUHIUgHYMQJkWAGRlZdWtUqXKnUQ0hIiOiNc8oV8QAAEQAAEQAAEQAAEQAAEQsCEQy8/P/2r16tXPt2/fngXeVkUm4M9teA3Y6+vLtOVka+ab1XN2zxs5iQT5RWzKxGKFAKBMTDMGCQIgAAIgkEQEzAQAWvp/Dv5XYAFAjRo1qu7Zs4fTTPFrKCAAAiAAAiAAAglIYPXq1a+1bt36RSLKKTkGgEUAfASAdgxAmRQAKIrSkIiGEtEAFj0m4NTCZRAAARAAARAAARAAARAAgTJIID8/f35mZuYL7dq1W+AwfNGd9E7BeLvXRQUAonY8JCd/zGw0FKLBexE7EZukXoEQACT19GJwIAACIAACSUhAEwA8VjI2Lf0/p7rV0v9X6tevX9NJkybNScLxY0ggAAIgAAIgUGYIrF+//tOmTZs+WCIAyC3JAlBYIgAoLmtHACiK0oyI7iOi60o+95SZtYCBggAIgAAIgAAIgAAIgAAIJA+BwsLCJWvWrHmhdevW2v1bmd3/TkF2N0F/r3VkffIqBBAJ8IvYJM+iMowEAoCknVoMDARAAARAIEkJWAkA0rXd/7wT7sUXX+x4xx13vJOkDDAsEAABEAABECgTBHbu3Pld3bp1Ob09ZwDQHwPAGQBYAMA/SV8URWlFRA8Q0ZXIbpT0040BggAIgAAIgAAIgAAIgECZIVBYWPjz+vXrR3fu3PnzHTt2aBne/Nj971dA32r3v2hWACdhAM+1jPjBuDacgvxOryftWoMAIGmnFgMDARAAARBIUgJmAgBt97+a/p8FAG+88caZ119//WtJygDDAgEQAAEQAIEyQWDv3r3La9asybvdNQFAHhEVEBFnAUh6AYCiKMcQ0TNEdDERpZSJSccgQQAEQAAEQAAEQAAEQAAEyhyBwsLCP9asWfNM69atp5sM3imI7iXY7xTgd3rdGMAXsTfW0YbsVgggEuQXsUmqdQcBQFJNJwYDAiAAAiBQBggYBQBpRGQUAFR+/fXXz+zfv//YMsADQwQBEAABEACBpCWwZ8+en2rVqnUDEWWXZADgYwDMBABJdTNDUZSKRDSs5IcFjiggAAIgAAIgAAIgAAIgAAIgkPQEcnNzv5kyZcoD/fr1W1syWJngv0jw3czG7+fYdRFfjHba/IpmQDCuB6fvxU6vJ9X6ggAgqaYTgwEBEAABECgDBDQBwOMlY03VCQD4ZnklIqr83//+94wBAwaMKQM8MEQQAAEQAAEQSFoCJQKAGw0CgHyTDABJcyNDUZTziegVIuLd/yggAAIgAAIgAAIgAAIgAAIgUKYIKIpSsHPnzlcvv/zyV7755hv+/sfFqxDAjyC/lzaMY3Aaj9mYrZ4zrg+n78dOryfFeoMAICmmEYMAARAAARAoQwSMAgB9BoBDAoDx48efMXDgwFfLEBcMFQRAAARAAASSjkCJAGAAEWXpMgBoAoCikmMARG+CRJqPoihHEdHoknT/kfYVzoEACIAACIAACIAACIAACIBA0AQKCws3rFixYnjHjh2/ttlRb/w+KBukt7PXXjP+1vcp8pqIjxpOEWGAyHdgpyC/0+tBT2/g7UMAEDhidAACIAACIAACvhKwEgBwetxDAoBx48adMXjwYN49hwICIAACIAACIJCgBHbt2rWiTp06egHAQSJKKgGAoijpRHQnEY3gLEYJOlVwGwRAAARAAARAAARAAARAAAQCIZCVlTVr/PjxjwwdOnRzSQci6fVFAvNubKxEASJCAnZfxnc9TzfHAjgF+Z1eD2Q+w2oUAoCwSKMfEAABEAABEPCHgJkAgG+cl9cJAKqMGzeuKwQA/gBHKyAAAiAAAiAQLwI6AUA2EeUQUW6JAKCAiBI+A4CiKF2IaDwRtY4XY/QLAiAAAiAAAiAAAiAAAiAAAlEnoChK7saNG0efcMIJ/923b1+xzl+3O/6dAvluX2fXnOrqbUQfG+30U+YUyPf6etSXh6l/EAAk5LTBaRAAARAAgTJMwE4AkEFElXj3HAQAZXiFYOggAAIgAAJJQ6BEADCQiDQBgJYBgAUAfNNHu/ETS6RBK4qSSkT3E9FIIuLjjFBAAARAAARAAARAAARAAARAAAQcCBw8eHDhyJEjbx81atTOElOZXfxcxS447xS49/t1M3/0z2k0RI4F8Brkd6qfcGsTAoCEmzI4DAIgAAIgUMYJiAgAqowdO7brkCFDXi7jrDB8EAABEAABEEhoAjYCgEJDBoCEEQAoilKXiN4hou4JPTlwHgRAAARAAARAAARAAARAAATiQKC4uHjXN998c+e//vWv73Tdi6Tglwng+yUUkPGLhyNyRIDRTsPgFMT3+nocZtt9lxAAuGeHmiAAAiAAAiAQDwJWAoAK+iMAIACIx9SgTxAAARAAARDwl4CJAICPAMgjooQUACiK0o2IJhNRfX9JoTUQAAEQAAEQAAEQAAEQAAEQKFMEYhs3bhx78sknv7xz507ODCcTaNcH92UD/Wb2sm3wRIkeXWBlq022WVDfS6DfqW7CLDIIABJmquAoCIAACIAACKgEIADAQgABEAABEACBMkKgRAAwiIiyiCiHiBJSAFCS8n84EY1Ayv8ysngxTBAAARAAARAAARAAARAAgcAJ5OTk/G/48OF3jh49eoeuM5Gd/qKBfCexgNPr7BbbiPikDcHuWAOtPT1biABMVhoEAIG//dABCIAACIAACPhKAAIAX3GiMRAAARAAARCILoFkEAAoilKPiN4lonOiSxqegQAIgAAIgAAIgAAIgAAIgEBiEiguLt49e/bse3v27LmgZASyO/KdxABWQX6R59klGQGAXfDfGOi3Oi5Am0in3fx2rzvVjfxigQAg8lMEB0EABEAABEDgMAIQAGBBgAAIgAAIgEAZIZDoAgBFUc4gog+I6MgyMmUYJgiAAAiAAAiAAAiAAAiAAAjEg4Cydu3acS1btnyloKAgVuKAU2CfzYzBeZGgvtFGpI5ZX1bPac+b/dY/Z3xs9n+r57Q5SloRAAQA8Xgbok8QAAEQAAEQcE8AAgD37FATBEAABEAABBKKQCILABRFuaRk53+FhIIOZ0EABEAABEAABEAABEAABEAgQQns2LHjs3bt2j24ffv2Ioe0+yJBeydxgBshgKgoQR+4N9vpb7f7X/ZIgKQUAUAAkKBvYrgNAiAAAiBQZglAAFBmpx4DBwEQAAEQKGsEElUAoCjKYCIaQ0SpZW3OMF4QAAEQAAEQAAEQAAEQAAEQiCeBffv2LfjXv/51x7Jly/Js0u/bCQCcAvuyr2vBfKujAOyOLDATAlgF/70cCZB0IgAIAOL5LkTfIAACIAACICBPAAIAeWaoAQIgAAIgAAIJSSARBQCKojxMROrnFRQQAAEQAAEQAAEQAAEQAAEQAIHwCeTk5Ky85pprbv7000/3lvTutJufzTQbkQC/mY1IPX0/To+11+1+618zPhb5v35ykkoEAAFA+O+7SPZYXFxMW7Zsoa1bt9K2bdvUn927d1Pt2rWpUaNG1LBhQ/V3zZo1I+k/nCp7BLBmy96cY8SHCEAAgMUAAiAAAiAAAmWEQCIJABRF4d3+rxLRkDIyPRgmCIAACIAACIAACIAACIAACESWQF5e3tq777578NixY7cajgNw2v0vGtw3ExXIPKcF6K38MXtde07jbsweYHxd5P/GObQSAtgJBCK3DiItAOAg9B9//CEF7aijjqKmTZtK1bEz3r9/P61cudKX9jIyMtSAOv9UqVLFlza9NMJjmzVrFk2fPp2++OIL2rNnj2NzlSpVojPPPJMuvvhi6t27N9WpU8exDhvIcmzSpAk1btxYqG0ro/Xr19OGDRuE2zjhhBOoWrVqlvZexyDrj7DjAoYs4GjWrJlqKTsOgeZNTfh9yO9HP0sQazYq8+Jmbry+T9auXUubNm0SnqIOHToQX8esip9rK6jrpZ8+2oELYv3r+oMAQHjVwhAEQAAEQAAEEptAoggAFEWpQETvEFHfxCYO70EABEAABEAABEAABEAABEAgeQgUFhZuHzVq1JDhw4f/ZXIcgEyw3s7W6TUGqs8u4JQpQG+vPRb5bWajTaZZ8N7tjv+EEAJEWgBw9dVX07vvviv1TuvSpQstWLBAqo6d8ddff03nnHOOb+1pDbEAoGvXrnTuuefS+eefTy1atPC9D6sGv//+e3rsscdo7ty5VFRU5LrftLQ0dQyXXHIJXXXVVVSjRg3LtmQ5PvLII/Tww5w50n158MEH6cknnxRuYP78+ep4rIrXMcj6I+y4gOEdd9xBL774omopOw6B5k1NnnjiCXrggQfcVj+sXpBrNirz4mZuvL5P7r33Xnr22WeF52j16tXUsmVL394joh37eb1MxPVvwgkCANHFAzsQAIFIE0iEbD4HDx5UM2Pt2LHj0M/OnTupcuXKVLduXfWnXr166m9RYWykJwXORY5AIggAFEVhFfVUIjorcgDhEAiAAAiAAAiAAAiAAAiAAAiUcQLFxcUH3njjjdsHDhz4UwkKu1T/Vrv/nYL8TgF+mT7ZTbsjC7TXzX7rn7N7rK0KN7v9IQDw8p7iXZr169en3Nxc6WYyMzPpuOOOk65nViGsYBHvph85ciTxLvSgyvLly2n48OE0c+ZM37v45JNPqE+fPpbtynL0GthkR2QDuxAA+Lss/BAAhLFmZdeJn5T0wgxuN+z3SaIIAIzMvVwvZRm7nW8/1r9N32VSAOBX9gbOZHP00UcHcqSNXz46rTt9hol4ZjFx8jPI16OY2cbP+Q8qC0qQcyLadhDZfET7FrFTFIWWLl2qZsniDFmLFy8mFiqIFD4uq0ePHqq4lwXERxxxhEg1KRu/1hlfCxs0aKCKF1JTOWt7sMUvv528DDgDj1P3gbwedQGAoihViWgeEZ0cCAA0CgIgAAIgAAIgAAIgAAIgAAIg4JlALBbLf/vtt2+77rrrltpkAnAK/suKAETseWx24gH962aPtec0Rk5HAshkAnCbIcDzfPnRQGQzAIwfP54GDx7saoy865iDL36UsIJF7GtKSgrdcsst9MILL1C5cuX8cF9t48CBA3TTTTfR5MmTiW9qBlEgAChN1ShiiEqgOaw17SUAGuaajcq88AqSnRuvQplEFQB4uV7KMnZ7vfSy/gX6LJMCAL/nrnr16nTMMceoP5yFZ9CgQcRBZS/Fbx+tfNGvr3hewzp27EhLlizxgsx13Shmtglq/v3MguIauA8Vg8zm44N7tG7dOnr66aeJP9PyDn+vhT/Ld+7cmXitXnTRRV6bO1Tf73XGfrIIgI8V6tmzJ1166aXUvHlz3/zVGvLbb5Hro++DiFODURYAlKT9Z3X52XHCg25BAARAAARAAARAAARAAARAAAQECRQXF+c899xzA4cNG/Z7SRWZXftOO/iNbYn8n90wszM+r/+/9ljmt97W+Fijl3SZACIrADj11FPpf//7n+CyPdyMb+DzjjhOUe+1hHWzSu8n7xiaMmWKbUp90XH99ttv6s58/h1kgQCgNF0IANwdARD2mo1n8AwZALxflWSvl2Fd0yEA8D63xhaCnjveDTt06FD1h1N7uylB+6j5BAEAqUHVqB1tE9b8e8mC4mZde60TRjYfLz5u2rRJFQ5PnDiRCgsLvTRlWfekk05SM339+9//9tx+GOuMM5JddtllqoCYxVJ+lDD8Zj8D/vvrBwrpNqIqAFAUhVNHfEBEfaUHhQogAAIgAAIgAAIgAAIgAAIgAAJxIVBYWLj7zjvvHDBmzJhNDpkArAL47LdIcN+tjVn7+ufMHmvP2f3Wv2Z8rM1FUokAIikA+PXXX6lNmzaeFj+n7OQUnF5LWDerjH6effbZNHv2bE8ihqlTp9K1115LWVlZXjE41ocAoDQiCADkBQDxWLMQADzr+P7WDFavXk0tW7a0tE+E62VYPgYcgEAGAOFVK2/IKbFHjRpFV111lXTleKyveF7DkAHg8CUS1vxzr0FljZJe9DYVwszm48bv/Px84qxhY8aMIX4cRunUqRONHTuWTj7Zfab0MNdZ7dq1VeECZ0jxKqwOy++A//6GsUxK9RFhAcBYIhoSFyjoFARAAARAAARAAARAAARAAARAwDWB3NzcTVdcccWAzz77bK9AMJ/7cQrmxwRs7Nqw68P4mv7/Zo+158x+658zPtZ4Jo0IIJICAN5999xzz7levFyR01d++OGHntrgymHdrDJzdNiwYfTUU0+5GsOECRNo4MCBgaX8NzoFAUDpaYIAQE4AEK81G8/gGTIAuLq8mVYSvV6GdU0POAABAYB/S8eypUmTJlG/fv2keorH+ornNQwCgMOXR1jzr+9VNguK1IL2YBx2Nh9ZV3nX/yWXXEKLFy+WrerZvmLFiqoI4Prrr3fVVjzWGQuzX375ZWKBstsSlt8B//11O3xP9aIoAFAUZQQRjfQ0MFQGARAAARAAARAAARAAARAAARCIG4GsrKzfzzzzzJuXL1+eYwjes09OAX/9616D/059mfmjf87ssfac2W/9c8bH2nwkhQggcgKAoqIiatSoEW3fvt3Twq9QoQJt2bKFatas6amdsG5WmTmZmppKq1atolatWkmNYe7cuWr2A2YZVoEAoDRpCADEBUzyCd0AACAASURBVADxXLPxDJ5BAODfFUr0ehnWNT3gAAQEAP4tHcuWypcvrx5FdOKJJwr3Fo/1Fc9rGAQAhy+NsObfuCD9yBolvMgFDOORzUfArUMmCxYsUIXCXr9ryPRpZjtkyBAaPXo08bVGpsRrnfHf2WeeeYbuueceGXcP2Ybld8B/f12N3WulqAkAFEUZTETjvI4L9UEABEAABEAABEAABEAABEAABOJLYPfu3cvatm1797Zt2/hMRKdAvN3rMiIAGVsGZNav8Xnt//rnjc9psLXgvj7IbxbwlxUBWNnHbZIjJwD47LPPiM829aPwTpVbb73VU1Nh3ayycvLqq6+mt99+W3gMnKL79NNPp3379gnX8cMQAoDSFCEAEBMAxHvNxjN4BgGAH1eff9oQuV6GdU0POAABAYC/S8eyNT6ve/r06cK9xWN9xfMaBgHA4UsjrPk3W5CiWVCEF7NLw3hl8xF197333lOPxwpTJGvnW9euXenLL7+kjIwM0SHENTsZO9m/f381g0F6erqwz2wY1vsj4L+/UmP2yzhKAgBFUS4hIk6zl+rX+NAOCIAACIAACIAACIAACIAACIBA/Ahs3rx53rHHHvtIXl5ecYAiAJmgv4gQgYHp7fT/N3usPaeBLhMigMgJAPr06UO8c8iP0r59e/rxxx89NSV7s6pevXrEP7FYjHbs2EE7d+70lIafz9vcvHmz2qZT4aD/SSedRGvXrnUy9f11CABKI4UAwFkAEIU1G8/gWVkXAMTjeil7TXd7sQw4AAEBgNuJcVGPM/Fw+muREo/1Fc9rGAQAh6+KsObfbC2KZkERWcdubeKZzUfE54ULF6op7PPz80XMQ7Pp27evemxZSkqKUJ/xXGeag3z0xIwZM4iPMxAtYfkd8N9f0eH6ahcVAYCiKGcQ0WwiquDrANEYCIAACIAACIAACIAACIAACIBAXAlkZmZ+0qJFi9ElQXX2xU2Kf6sgv13w360wwOijPqBv9Viro7EWEQHY7eqXzRAQ+hxHSgDAAfOGDRv6uitn+fLlUul7jTMge7PKGPTNy8uj9evXq7v4x4wZ42pnPtflna1O5a677qIXX3zRyUz4db6pxz8i2QQgACiN1bgW3nzzTeKdZ06FU9MePHjQyUx9nY+66Natm6MtC2sGDRqk2smu6WOOOYaOPfZYxz6MBtdddx1dccUVtvWisGajMi9u5sa4xmQn6d5776Vnn31WuBpna2jZsqWlvezaisf1UtbHINe/MHiTyws/lZKS8njJS2lExFsx+YY8R2MqEVGVsWPHdh0yZMjLHvqJVFXZufPL+eeee47uvvtuoebC8lEf4IIAQP7vmtBkmhg5BRbDmn8r/0WyoLgdu1O9eGfzcfKPP4t36tRJFedGsfD7+PHHtUu6vYfxXmead1dddRW98847wjjD8tvpfSrscIQMoyAAUBSF1eg/EdGREUIDV0AABEAABEAABEAABEAABEAABHwiMG3atCcuuuiirwSyAMgG+s3svYoCeNRORwNoNnpb/XPG1zWSxsB+wooAIiUAeOGFF4Rvsouu6dtuu41eeuklUfNSdrI3q+wCcgcOHKCLL76YeIeUTOnXrx9NmjTJtsqaNWvUHYoFBQUyTR9my/UvueQS4pTHxx13HFWvXl19PTc3V81CsHTpUpo8eTLNmjWLCgv5SJB/CgQApbG7Dc5ysP3PP/8Umsf69evTli1bhGw1Iz/XtFTHBuOor1nj2IKeF+4v7LmJmgBAzzyo62XYjL28R2zqIgOAANjGjRtTkyZNDmXk2bhxI7EoT7b06tVL3ekqUmTXl0ibZjYQABDpM6jEg7vZvMj6EY8sKG7XnF29KGTzsfMvOztbPR7r559/DmL4vrUpKviVXWe+OWjSUNQFUkGOPcy24y0AUBSF0/3zzv9zwhw3+gIBEAABEAABEAABEAABEAABEAiPQHFxce5tt902eOzYsRsERAAcFBcJ7IvYWLUlchSA0YaBmR0NoH9ee6zB9ZIJwI04ILRJjZQAoG3btvTLL7/4OvhatWqpAdLy5cu7alf2JptT0Hf37t108sknq1kBREuHDh1oyZIltuYsLPj0009FmzzMrlKlSvTUU0/RrbfeKpR+lI814MChXpQAAUBp9E5rwWqygg40+72mXS06IlUME+U1axxX0PPC/YU9N1EWADCPIK6XYTN2+/5wqAcBgABYs2vwd999R4899hjNns1xDLHSunVr4c8msuvLjwwT8cxicuSRR9K2bdscQZaVzDay8x+PLCiOk+XCIArZfOzcvu+++2jUqFEuRmZehVP116hRg3Jycnw9TqBq1aqqALROnTq2vsquM/11ho8/4M/x2o+i2H1PdUbGR5V98cUX1L17d0djL347Nq4zEMlAJdNeFGwjIAB4iIgejQKLqPmgxIh2bSii7WsKafsfhbRtTSHt31ZEedkK5WXHSn4Uys+OUX6O4ulowKiNHf6AAAiAAAiAAAiAAAiAQNQIpFdMpYpVUqhiFf6dShUqp1JGlXK0r+oPVNz4R2rRooX607x5c6pcuXLU3I+EPwcOHPirTZs2t2zatInPTxQJzBsD/F7/L9KnkzCAWcqIAPQ3R6wea22azVNkjwKIjACAA9ycmjOIMmXKFOLzNd0U2ZtVIkHf559/nu655x5hd3gH47p16yztv//+e+rSpYtwe3pD3hHFgXze8S9bOIDCN9m2bt1KEACUpieyFsyYBx1oDmJNy66dRFizxjEFPS/cX9hzE3UBADPx+3oZNmPZ94agPQQAAqCsrsEc8OJMNzNnzhRohahu3bq0fft2Idsor68wrmFWkILuOyrc/fQjqCwoQgtZwijq2Xw48wd/sXeT/UPDUK1aNerduzdxNpDOnTsTC1/KlSunvszZD37//Xf1ejJ16lRauXKlBL3Sprfccgu98sortm34tc74uvbll1+qfrsVZLKjnG0lMzNTPZbKrvjltyfACVo5ngIARVH4rLE5RMTHDZX5suOvIvp9QS79/l0ebf61gHb8VUhFBd6ENGUeKgCAAAiAAAiAAAiAAAiAQGAEUiiV0mh1wWT6NnvYoV5Y2M9Hkbdq1UqNq5111ll0yimnuN5EHJj7cWo4MzNzZosWLfiscWOgXTT1v97OThDgJBbwIgZgemVeBBAZAcCQIUPotddeE1rSvDOGb76JpvLs2bMnff7550JtG42CuFk1b948Ovvss4X9qVKlCmVlZVna9+/fnyZOnCjcnmY4dOhQevrppyk1lbM6uit8w4/PoB8zZgzxOfNWJQiOTh7Lnos8f/586tq1a9zHUBYCJYmwZo0LIeh54f7Cfp8kggDA7+tl2IydrlMuX4cAQACcnQhr7dq11KxZM4FWSFUEcwpxkRLl9RXGNcyKUdB9R4W7334EkQVFZB3L2EQ9mw8LVTlLhtty0UUXqZ9xGzRo4NgEi4tef/11NUvW/v37He3NDNLT09WMI3bCXL/XGfsxZ84cGjBggK3g2G5ALNbjTBB2JQi/XUFOwErxEgAoilKXiH4iovoJiM0Xl/dtLabV3/wd8P9tQS7t3VzkS7toBARAAARAAARAAARAAARAIAwC5gIAs545SzaLAThuxz+clZuFAmW1fPDBB09fccUVX1scBeCU1l806C8qFNAC+VYCBLOMADx1VscD6F/THut/2z02vqZfIpHLBBAJAQDvyuGzzHkXjUi56aab1HN9OaWnSOH0lBs2bBC6eWdsL4ibVTKBB/bHLgNAcXGxyo5TecoUvoAtWrSImI3Xwjuf+CY1ZxOwKkFwdPIbAgBzQvGYC70nibJmjfSCDmBxf2HPTSIIAPy8XsaDsdN1yuXrEAAIgHPKwsIpvEU+dzRt2pR4HYqUsN/DIj5pNmFcw6z8CbrvqHAPwg+/s6DIrBkn26hn8+Hd+O3bt6dYjL8fypV69erRq6++6iqDGGfG4p38nB3LTeGsZZy9LOzP1Hykwf33368KHmSZ8ZFrf/31F3G2hLD9dsM40erEQwCgKAorxGcRkfP5DokG1MFfTtX/4/QcWvRBNmV+l0exGHb4J9kUYzggAAIgAAIgAAIgAAJlhoC4AMCI5Oijj6ZrrrlG/eH7WmWtFBUV5Q4YMOCWSZMmbRIUAcgG/a2C/35mBeBpC0IEIBvoj9uXykgIACZPnkxXXXWV8HuIz/A96qijiG/Ki55dyWfcDxv2T5oP0c6CuJnL2Qg4/bBo4RQk7IdZ+fbbb9Ud+DKFdxctXbqU2rVrJ1PNk20QHJ0cggDAnFA85kLvSaKsWSO9oANY3F/Yc5MIAgA/r5fxYOx0nXL5OgQAAuCcBAD8OWLTJv4Ma19OO+00WrhwoZOZ+nrY72Ehp0qMwriGWfkTdN9R4R6EH35nQZFZM062Uc/mM3jwYBo/frzTMEq9fuaZZ6op8Vkk5KW8++676o0C0e8qWl+8w4CvTVZZB4JYZ/pxfvHFF+pxB7J+P/TQQ/Too9bHxAftt5e5inrdOAkAHiSix6POxi//lBjR6m9z1aD/8s8PUsFBeeGQX76gHRAAARAAARAAARAAARAAAb8IuBcA6D3ge4PXXnstXX755Z7vFfg1sjDa2bdv319t2rS5a8uWLflEJJL+XySor9mY2QaREYBRWYkAtMC802+tDT32hBABREIA0L17dzX1pEjh3fC8E49vjnG6dhYDiBQ+/5N3qsuWIG5WcVBi5MiRwq7ceOONNGHCBFP722+/nV5++WXhtthw+PDh9Nhjj0nV8WocBEcnnyAAMCcUj7nQe5Ioa9ZIL+gAFvcX9twkggDAz+tlPBg7Xadcvg4BgAA4OwHA3r17qWbNmgKtEP3nP/8hDuSJlLDfwyI+aTZhXMOs/Am676hwD8IPv7OgyKwZO9uoZ/Ph4DWf58e78WUKB/35iDGu60e544476KWXXpJuio9FGzRokGm9INaZsaOBAweqxxnIFBZVccY1qxKG3zL+JpJt2AIARVG6ENE3ROQ9VVzEQRcXEv3wfhbNGr2fdq4rjLi3cA8EQAAEQAAEQAAEQAAEQECOgD8CAK3PjIwM9fg8Plq7UaNGcq4kqPWqVas+P/7448fqguhOO/RFA/thCgGYfpkUAcRdAMA3imR28nPafz63nsu4ceOIjwMQLSwW6Ny5s6i5auf3zapff/2VTjnlFOHzhNmHJ554gh544AFTv9u2baueFSpa+LgAvplcoUIF0Sq+2Mly5Auo14voxo0bafPmzcL+z58/XxWVWBXZMTjtPrXqJ2qBkmOOOUY6zQ2vcSuRS6KsWeP8BD0vQVxvnBZ/1AUAfl8v3TD2e/07zYng6xAACICyuwbLCEs4jXefPn0EevT/M4NQp4JGYVzDEuXvmtu/z06og/ic4HcWFKcxiL4e9Ww+ixcvVj9vy5b33nuPrrjiCtlqlvZ8zFnHjh1p1apVUm2ef/75NHPmTNM6QawzY0d8PEqrVq1o27ZtUn4vW7aMTjrppLj5LeVsAhmHKQBQFCWdiH4iotYJhEja1cI8hRa8lUWzX91PezcXSddHBRAAARAAARAAARAAARAAgUQg4K8AQBtx+fLl1YwAnHGc7x0neVFGjBhx72OPPbZaUATgVgAgWo8D+WbZCKwyFGiBf56meIsAQj8KIO4CAE4V+fDDDwu/R1asWHEodf2uXbuIA9pFRWJf2u120ls54OdNtuXLl6s3FTMzM4XHy4acirNHjx6mdUTPMNYqc7pW2R09Us5aGMty9KNP2TYgAJAlZm3PR1xMnz49odes0fkwgmey7xOvQawoCwCCuF7ynMoydvOusFv/btozqQMBgABIs/fHwYMHiXfWslJX5Ixr/hvLATD+YC9SZNeX1/ewiE+aTRjXMCt/gu47KtyD8ENGrML83XzWlVlHmm3Us/nIZoHicclk+5BhtnLlSurUqRPl53PGPLHCQl3+nlOlSpVSFYJYZ2ZeTZkyhS677DIxh0usRowYYSkADctvKYcTxDhkAcC9RPRMgqCRdrMwX6Gvxx+gOWMP0IGdYvcQpDtBBRAAARAAARAAARAAARAAgYgQCEYAoA0uLS1NjffxvRu+95WsZe/evWsbNWp058GDB4slRQB2QX1jBgCr/xsD/nbHBFiJA/SBf54mq/9rr9n91r+mTblZYF/2iIBAlk9cBQCcnpMVMrwjXaS0adOm1A4aPqPSaoeMsc2qVauqqUArV64s0p1qI3uzis+/5B8e244dO9RUmOvWraO3336bZs2aJdyvZsi7aHg3jVnhXUWcdkSmyOxklGnXyVaWo1N7QbwOAYB/VK0CoIm0Zo00gg5gubneeA0exlsAEOb1UpvPMK5FEAD4dy3RtyQ7d2effTadc845aqB/+/btxFlhFi5cSDt37hR2kI/YufXWW4XtZX0MM8NEGNcwK1BB9x0V7rJ+OF3Dg8iCIryYHQyjns2HPz+zkEy08HeDTZs2UfXq1UWrSNnx8Vuc0UumTJs2jS688MJSVfxeZ3Y+nX766fTDDz8Iu92uXTtisbZZkfU7zOuj8ADjZBiWAEBRlKOIiHd1iH9ZjhMTN90unb2F3r93N2VtZGFNSsk9HzctoQ4IgAAIgAAIgAAIgAAIgEBiEAhWAKAxYBE/32fnLN4VK1ZMDDSSXs6cOXNCr169eMenPnhuFYz3I/DvRhCg+eYlGwCTMWYN0Gjpg/pWj/Vk4y4CiKsAYN68ecQ36EWLWSr8d955h6655hrRJmjSpEnUr18/YXvZm1XCDQsafvbZZ3TBBReYWrOw4OijjxZs6W8zPi6gdevwMzrGm6MIJAgARCiJ2VgFQBNpzRpHGnQAi/uTfZ84BY+cZiveAgAn/2Rft7team3JMpb1ge0hAHBDzblOGHOn9+Liiy+mjz/+2NkxnUUYPrpdX2Fcw6xgBd13VLjL+mF3DQ8qC4rUgrYxjnoGqlq1atGePXuEh3vppZfShx9+KGwva8hiDhYyyxQrAZKf68zJnyeffJI4m4JoSUlJUTMdpKdzFvnDi6zfon3q7dxeH930FWadEAUA/Efv4jDHFkZfOzcdpNfv+5EWTl9PNVObU0ZabQgAwgCPPkAABEAABEAABEAABEAg7gTCEQBow2zWrBnxd3netJxspbCwMPfcc8+96ZtvvtkrKQIQ3emvtzPW0e/st3tNVABgdSwAT5tZ8N8s2G8M7ssE+0M7CiCuAgA+J4N3xouWv/76q1TAOzs7m+rVq0ec1leknHHGGcTnloqWMG5WWfnSoUMHWrJkiaWrvCOHd+bIFE4nyjdFwy7x5Cg6VggAREk521ndgE2kNWscZdABLO5P9n0CAcA/s+R0vdQsZRk7r/bSFiEEIHAEgJuJkajDu25ZYMiZg2RKlNdXGNcwK1ZB9x0V7rJ+xCMLisx6trKNejYfDkDLKu4nT55MV155pR94LNto0aKF1DFg999/P3EA3lhk15mXzwpLly6ljh07SnHh7GdHHcUbyQ8vsn5LdVpiHMLfXzduea4ThgBAUZTziWimZ2cj1ECsWKFPX/mN3n9mFeXlFJFCMQgAIjQ/cAUEQAAEQAAEQAAEQAAEgicQrgBAG89FF12kCgHMvhsHP+bgesjMzFzQokWLFwMUALgRC1gF/Z2yALgVAdjt/I/cUQBxEwAcOHCA6tevLxy4P/XUUy1TUPI5Gx988IHQyuadKX/88Yd69IBICeNmlZkfTZo0oS+++IJatWpl6eZXX31F5557rsgwDtnwTVHRs4ylGnYwjhdHmTFAACBDy97W6gZsIq1Z4wiDDmBxf7LvEy839bm/ZMkAIHK91OZTlrGbd0UIAQgIANxMjGAdPsOa31v8eUG2RHl9hXENs+IVdN9R4R6GH3ZrUiQLiuyaNrOPejYfDkDz3wWZ8tNPP9EJJ5wgU0Xatk+fPjR16lThetdffz298cYbpexl15mXzwr79++XPhbhf//7H3Xq1Mmz38KgdIYh/P1145bnOkELABRF4RyVq4hI7Auy5xEF38CuzQdp1PULafWif479gQAgeO7oAQRAAARAAARAAARAAASiRSA+AgBmwEcM/t///R+xGCCZyqOPPjry4YcfXikgApAJ5tvZirajzxIgmwlAC9zrjzfgadM/b/Z//XPGx/pplxEG+Lpc4iYAeP3112ngwIHCg7E7h5dvePbu3Vu4LU5l+fjjjwvZy95kE2rUwYjPLf3888/pyCOPtLX8+eefic/alCl8vmnDhg1lqvhiGw+Oso5DACBLzNre6gZsIq1Z4+iCDmBxf7LvEy839bm/ZBAAiF4vtfmUZezmXRFCAAICADcTI1inZs2axOn/WVzYrVs3SktLE6wp/x4Wblhn6HZ9hXENsxpP0H1H5X0dhh9WjEWzoLhZc8Y6Uc/mwwFoFg7LlO3bt1PdunVlqkjb3nTTTTRu3Djhej169FDFwMYiu868flbgswwLCgqE/f70009Nb3DI+i3coQ/XRzd9hVknBAEAf654OMwxBdnXkllb6MXBiyhrT/5h3UAAECR1tA0CIAACIAACIAACIAACUSQQPwGARuP222+nUaNGxWVTbhAzsm/fvs1Nmza9e//+/UU6EYB+t71owN4u5T+/ZtaOU9teRQBGIQAjTGgRQNwEAJy6nm8gihS++b5582Y11b9Z4ZtSHCzfu5ePn3AunHqDdy+lpqY6Godxs0rvBO8O4mMRKleu7Ogbp/OvU6eOo53eYNmyZcQBs7BL2BzdjA8CADfUzOtYBagSac0aRxZ0AIv7k32f8E7lkSNHup64e+65h55//nnh+qtXr6aWLVta2sv6L9yxhaHM9VJrIgwf3QZoJXhAACABy4spf+4YOnQo3X333ULNRHl9hXENs4IUdN9R4R6GH2aMZbKgCC1kB6OoZ/OZPXs2nXfeeVJDDSND1gMPPEBPPfWUsF+nnXYaLVy4sJS97DrzKgDg7xr8+U20TJo0ifr16+fZb9H+9HYh/P1145bnOkEKABRF4V3/vPufswAkdCkuUujNR1bQ1Fd+I0UpvcECAoCEnl44DwIgAAIgAAIgAAIgAAIuCMRfAMBO89F6nMH86KOPdjGG6FX58ssv3+vRo8enDgIAfTBeJtgvGvi3EgMYRQCiRwGY7f4XEQTwBBm/gIru+Dez83XC4yIA+O2332xT2xtH2L17d+KbeXZlwIABNGHCBGE4s2bNEro5KHuTTdgBnSHvOLr22mvpxhtvtA2uGdvmGxt8xqnMrpzXXnuNBg0a5MZNT3XC4OjJQSKCAMArwX/qW92ATaQ1a6QRdACL+5N9n3BgkhWEbsvNN99MY8eOFa4eBQGA2+ulNkhZxsJwdIYhBCAgAHAzMR7qcDDrv//9r6NaN8rrK4xrmBXioPuOCvcw/DAyls2C4uFtcKhq1LP5LF++XFrsunHjRmrUqJEfeCzb6N+/P02cOFG4jwsvvJCmTZtWyl52nXkRAPDntvT0dCouLhb2m7OY9ezZ07Pfwh2G+/fXjVue6wQsAPiIiC7x7GScG9i3M4+euHIB/bbYWqwCAUCcJwndgwAIgAAIgAAIgAAIgEDoBKIhAOBhH3HEETR58mTT78uhY/HYYVFRUf6pp556y7Jlyw6UBL/NMgD4IQCQEQ5YBf6tBAD655mIXgCgPdY/rz02+61/zvhYT1tUGOBxhv6pHhcBwH333ScVtOKzMq677jrbQc+bN4/OPvtsYTCXX345vf/++472sjfZHBs0GPAO3uHDh6s319wU3vXFZ52KlgsuuID4yISwiyzHvn37Ev94Kayq4jSkogUCAFFSznZ2AdBEWbPGUQYdwOL+eKdf586dnQGXWHAA/9VXXxW2NxrecMMN6llEomXt2rXUtGlTS3PZ97lov5qd1+sltxO0j9wHBACyMytmH8bc2XnStWtXmj59uvqB3aqE4aPb9RXGNcyKS9B9R4V7GH7oGbvJgiL2brO3ino2n23btlH9+vWlhrp48WJVkR9k6dWrF82cOVO4CxbssnDXWGTXmRcBwJ49e6hWrVrCPrPhjz/+SO3bt/fst1SnJcZur49u+gqzTlACAEVRWhHRL0SUEuZ4/O5r29psGtHnG9r6V5Zt0xAA+E0e7YEACIAACIAACIAACIBA1AlERwDApMqVK0d8NLpTrDPqVNm/b7/9dmq3bt0+CEEAYCUCcDoOwEqUYHZMgNXuf6MQgIcuciSA3k4/nckvACgqKiJOwc8350QK73DnczmrVatmax6LxdR2t2zZItIs8XmWW7dupRo1atjay95kq1q1KmVl2d980HfIaT84Lb+TH1ZOcopTp+wI+roZGRn0+++/q6zCLLIcvdys1Mb14IMP0pNPPik8TAgAzFFdf/31xD8yhW8Wt27d2rRKoqxZo/NBB7C4v19//ZXatGkjjJoD+DK7CY0N8xnnLJQRLRwIsLtWyb7Pw75e8jhlffR7/YuydrBDBgCfQMo2wym8n3jiCctqsutLtn+2dxvgCuMaZjWeoPuOCvcw/PCaBcXNmjPWiXo2H96tXr58eeLvBqLllVdeoVtuuUXUXNqOfWFRwo4dO4TrPvzww8Sfh41Fdp15+UzNn43PPPNMYZ/ZkL9f8dFsXv2W6rTE2O310U1fYdYJUADwNhFdHeZY/O7rzxV76YFeX9O+HbmUXj6VUlKttQwQAPhNH+2BAAiAAAiAAAiAAAiAQNQJREsAoNF65pln6N577406PFv/CgsLD7Zt2/b2zMzMHCLyIwOASKCfbZyyAlhlHtAH+UWOBeDxOx0LoDEyigKMz+tZhioCCD0DwIwZM4h3oYsWDlhbBRKNbaxZs4b2798v2rS6c5Z30NoV2ZtsfKb2Rx99ROvWrRP2g29W8a78lBT5zRfjxo2jm266SbgvNuS0nJyeM8wiy9HLzUptXBAAmM9wPOZC70mirFkjvaADWNwfC5gaNmwo/Nbs3bs3TZ06VdjeaHju1fCmQwAAIABJREFUuecSn+UsUvj6xAKu1NRUS3PZtRX29ZIdl/XRj2uRCF9JGwgABIBdffXVxD9c8vLyaPfu3eoP717+/vvv1YwbZmcE2zXNYkT++24lhJFdXwLDKGXiNsAVxjXMajxB9x0V7kH74UcWFDdrzqxO1LP5cACaBcSi5ayzzlL/PgRV3ATS+fPS4MGDS7kku868/B176KGH6PHHHxfGwhnN+Hpr9llB1m/hTnWGbq+PbvoKs04QAgBFUZoRUSYRpYU5Fj/7+nnBDvroxdVUu2EG7duRR78s3ElZu/MotZz5Z1UIAPykj7ZAAARAAARAAARAAARAIBEIRFMAwOTuvPNOev75513FBKNCftasWVPOP/98PrvQrQDALujv5jUt+G/MDmB1PIBZ2n/jc4zbTAigPa//bfdYm7bkFgBcfPHFUmnZg1zMJ598Mi1dutS2C9mbVXyT7bTTTiPe5SxTnnrqKRo2bJhMFdWWMyk0aNBAOojx9ttvHwqMSHfqooIbjrzzyUuBAMCcXjzmQu9JoqxZI72gA1jcX05ODlWpUkV42derV084m4qxUd4hyUFM0YwlHPh0Eli5WVthXi+ZgRsfvV6LhCdU3BACAAFWTkGvTZs20ejRo9UP2zKFg7AjR440rSK7vsLMMBHGNcyKY9B9R4W7rB/xyIIis9btbKOezadbt26cjk54uGlpabRq1Spq2bKlcB0ZQxYjvfvuuzJViI8343EYi+w6c7oWWjnFWQtOOOEElYto4ePY5s6dm3DXR9HxxcsuIAHAeCIaGK8xee135fwd9OdPe+jfg5urO/+5rPp+J70wcCHtWJ9jmgkAAgCv1FEfBEAABEAABEAABEAABBKNQHQFAEzymmuuoUmTJtluuIsy8fz8/KxmzZrduWXLljxdkNxMDCC6u18fwDfWcfq/VfDfSQwgIgLQ7/B3OgLAGOAXDfib2Xme/lAzAOzcuVPd3VpYWOjZcb8aWLFiBbVr186yObc32fr160dvvfWWsJt843HOnDmmN/qcGunSpYu6m1GmcIp2TjfOqWS9Fu67oKCAePeUVXHL0YtvEACY04vHXBg9SYQ1a/Q56ACW1h+nLZa5RvKRHs2bN5d+qyxZsoQ6deokXK9x48a0fv16W3u3ayvM66VbH4VBhWMIAYAAZ9Gg1/Dhw23T+hu74s8M/NnBrER5fYV1DTPjEnTfUeEu60c8sqAIvHWETKKezeeFF16gu+++W2gsmlGHDh3ohx9+UM/k87N8/PHH1LdvX6kmWaDHxwWY+SK7zkSvhUYHX3rpJbrjjjuk/OY6t912W8JdH6UGGQdjvwUAiqJwuqm/iKh8HIbjS5e7Nh2kI+pWpM2ZB+ivn/fS0cdXp6ata9D08b/T6/f9aNoHBAC+oEcjIAACIAACIAACIAACIJBABKItAGCQQ4YMobFjxyYQ08NdnTp16uQ+ffrMMhEAGAPvZv93Cuqbve5Ux3gEgJ0gQeRYAB6wyFEA+gC+1WMNnqgowPO6CFUA8OKLL9Jdd93l2Wk/G+AbW+yXVXF7k43Pym7VqpXUWZ+8m3f58uXqGaEyxS3Xzp070+TJk4kDe24LH13A54jzrqY+ffr4ztGtX1wPAgBzem7XtJe5MNZNhDVr9DnoAJbW3/HHHy+12+7111+n/v37S0/Pc889R0OHDhWu1717d5o9e7atvdu1Feb10q2PwqDCMYQAQICzaNCLBTec4YLTVosUu2wYUV5fYV3DzBgG3XdUuLvxI+wsKCJrXMQm6tl8+Fiw4447TmQoh9lwyvtHH31Uup5VBT7ah0VDfPyITOGMAZyty6y4WWeymWw2btyoHsGWnZ0t4zatXbuWmjZtGje/pZxNIOMABACjiej2BEJwyNW1P++j76ZuoCvubUvrftlLj142X93xX69pFXpixlkUixE90HMOHdidT0SHH68HAUAizjh8BgEQAAEQAAEQAAEQAAEvBKIvAODRid7D9EIiqLo5OTn7GjdufM+ePXt417fT7n+r4DzX036MWQC8iACcRAhaYF/vt1VGAEaovWb2WHtOQx0JEUCoAgC+Afbzzz8HtdZctVu7dm313G0+s9Lvm2wffPCBGhyXKWeccYaaOlNm9xGn5eab63yusWzhQAanQOY0xDKFU5XzDVJOncypxD/55BMIAAwA3V64y0KgJBHWrPH9EPS8aP1xMH/ixInCb0fOpsBnC6ekHH6T064BDniedNJJUkID3iX92GOP2frlJSgR1vXSi4/CkxK8IQQAAoxlrsGyWUlYtMI7dI0lyusrrGuY2dQE3XdUuLv1I8wsKAJvHWET2fcNNxxmBqq2bdvSL7/8IjweNuSMXN999x2deuqpUvXMjBVFUY8E++qrr6TbmjJlimXWALfrTMaJCy+8kKZPny5ThVjAuHLlSss6Yfgt5XACGfspAFAUpQ4RrSOiSgmEQHV169psur3LF1SjXgaNnt+D5n+0jl65ebEa5y8qUmjEh2dQiw61aViPObR1bVapz8YQACTajMNfEAABEAABEAABEAABEPBKIDEEADxKzrQ4ePBgrwOOS/3Jkye/ddVVV31t2ClvF3y3OxJANOBvJRgwOwrA6RgAEQGAaPDfeEQAz4nojn/fjwEITQCwbNky4tSaUSycmvPiiy82dc3rzSo3N9B4V+6oUaOkUI0ZM4ZuueUWqTp64wsuuIBee+01atCggW0bvEOSed1///3Eu4O0AgFAaWwywSd97bISKIn6mjXOaNDzovXHO/oHDpQ7kvXll1+mW2+9Vfj9z2eYOwXzjY1xIODf//63bR+JcL306qMw5GANIQAQ4CtzDeYMF3wMj2j58ccfqX379qXMo7y+wrqGmTEMuu+ocHfrR5hZUETXuIhd1LP5yB7voY25SZMm9N577xFnZ3BbWCjLRzzwZ2vZUrFiRTWDWNWqVQP5bmLnD4sWnn32Wbrvvvtk3aYJEybQjTfeaFnP7ftD2pEkrOCzAOBJIro/0TDFihV6+prvaMX8HXTRzc2p711taMuaA/T4fxbQ5j8OUINjq9Fjn55F+XnFdH+vOZS9p6DUECEASLRZh78gAAIgAAIgAAIgAAIg4JVA4ggAUlNT6cMPP6RLLrnE66BDr3/gwIFd9evXH3bw4MHikmC3VcBd9BgAKxGAzPNmQgBjBgL9/+2OA2CmxswA+ue0x/rfdo+1ORIVBrie09AEADfffHNkz7LgoJbVLhevN6s2b96sptA8cOCA8CTxTt5PP/2UevfuLVynqKhI3Xnz22+/CdcxGvKuJ97NxaIFTpvKRxFUqFCBeAybNm2ib7/9lqZNm0ZZWVml+oAAoDR2meCTvnZZCZREfc0aZzToedH64ywpnC1FpvA144knnqBhw4bZZgLgbB0PPPCAtMCIfdm+fTvVrVvX1q1EuF569VFmXgK0hQBAAK7oNTgWi6m7+WX+Tq9YscL0fRrl9RXWNcxsaoLuOyrcvfgRVhYUgbeOsEnUs/nw3y1ee7Jp7BkAf/Hm7y5PPvkkValSRZgJG3755Zeqan/dOt5kLV+chMBe1pmdN5mZmWoAnzMgyJYWLVqo2Rb4u4RVCcpvWV8T0d4vAYCiKBWJaBsRHZFIHBSFKBZTqCg/RgUFxVT1iPK04bf9VLdJZTqwK582/XGAGh5bjeo2rkwfj/6V3nx4henwIABIpFmHryAAAiAAAiAAAiAAAiDgB4HEEQDwaHlDwA8//EAnnniiH4MPtY2XXnrptTvuuGOJy2MAZHf9ByEEED0OgLnqxQDa/+1+a3NhDPgnhwCAd43zzvK9e/eGuuhEO+ObVbybnQPexuLHzarx48dLp++oXr06cdaEZs2aiQ6DZsyYQbyTPx4FAoDS1EWDT8aaUQuU8PEYVkdk2K01Hr/TGfNRXrNhz4vWHwcjeQ3wObqy5eijj6YBAwbQKaecol5zOdUyHw3Cx5x8//33xNkFWMwjW7i9RYsWOVZLhOulrI9Brn9HoNYGEAAIwBO9Bv/f//0f3XDDDQIt/mNiJYiRXV+iPko5Z2Ec9N8WOx+D7jsq3L36EVbWKD/Wk9ZG1LP5jBw5Uj1Lz23hbACchu/88893bGLnzp1011130TvvvONoa2VQs2ZN+vPPP4m/B1gVr+vM2C6LA5977jmVE39nc1N4l8Kll15qW9Vvv934mah1fBQAXE5E7ycah8lPrqLaR2VQpx6NKL18Kq2Yv5X+7/4VdFqfRvSfYe2oYuW/hSdLZm2mV25dQnu2HTQVxEIAkGgzD39BAARAAARAAARAAARAwCuBxBIA8Gh5Yy7HBa2yAnolElT9P/74Y2Xz5s1f1gXH9Wn1RXf+63ftW6X4157X/zarZ3fMgFkmAKtsAMad/3ZHATil/xcN+Pt2FEAoGQDef/99uvLKK4NaW760+8wzz9C9995bqi0/blZxOs1u3bqp53TLFE4vvHDhQlX5I1p4xxELDsIuEACUJu42sBO1QInbtcQ70nm3uVOJ6po1+h30vOj7c5tW2Ym129ffffdd+s9//uNYPRGul7I+Og7awkB0/btsHwIAAXBO12DOQvLmm2/SoEGDiANgoqVcuXKUn5+v7hA2Ftn15eSjqE8idmFew8K+fkaFu1c/wsoaJbJeRG2ins2HU/Hz2t+2jTc9uy9NmzalXr16UefOnVXBMGfE4cwCLAb6/fffaebMmerO+cLCQvedENHzzz+vigjsipd1xt9J9u3bRyxW+PXXX2nWrFn0xRdf0IYNG1z7zUe8LV682DYDETfuxW/XziVJRR8FADOIqFciYVkyawuN7Pst8dqt07gypaWl0M4NOVRUGKOU1BQ6um11qn9MVdq3I4/+WrGHcg8WqzZmBQKARJp5+AoCIAACIAACIAACIAACfhBIPAEAj/qKK65QjyZMpBKLxWIdOnQYunz5ck6F7hT8N0vPLxLwtwr0G0UBRjur/oxBf73fZhkBeEpkjwJw2vUvKgpwtRxCEQCcd955NHv2bGEHOeXmnXfeKWxvZsipVB988EHhNlq2bEmrV68uZe/XzSpOq3nCCSdI76zp37+/umtXtPCNWObNfodZIAAoTdttYCfoII3smna7jkQDoFFds8ZxBz0v+v44rXKjRo1cpS12O19W9TjQsX79eqEsELJry+o9EuT1UtZHtzxF17/L9iEAEAB3xx13HPoswbtad+/erWbE4N8cqOOjdvjsddnStWtXS0Gf7PoKM8NEmNewsK+fUeEu64fZNTCsrFGy697OPurZfNww9ZOPaFucxYe/i/DxW3ZFdp3przMFBQXEn7v8KpypgIP/vEPBqXjx26lt/esiGahk2ouCrR8CAEVR+BynzURULgpjEvFh1+aDdFvnWZS1J181Ly6MUUwhKpeeqt5ySUklVQigxBT1J71iGikxolQIAETwwgYEQAAEQAAEQAAEQAAEygCBxBQA8MS89tpr6qalRCrvv//+h1deeeUckywAZhkA3IoAnIL9Tq+b9WsW7DcTA7gN/uuD/CIB/8TJAMCp9XnXDKe1Fi0//vgj8e53L2XHjh1qCmyZXX282/600047rFvZm1V2Qd+nn36a7r//fulhTZo0ifr16ydcj49aOPXUU4mDaGEVCABKk4YAQCwDAJOL4po1zmjYwbO7776bXnjhhbDewpb98HXrvvvuE/IjEa6Xsj4K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LAgggAACCCCAAALlKUAAgABAec5ceo0AAggggAACCCCAQKEECAAUSjbb85YgAJC6JUBcSi7C2x/Of9tfZ/s53bmc13A+7U8FALdJQwAg27dTRbYnAFCRwxrMTREACMaRsyCAAAIIIIAAAgiUpwABAAIA5Tlz6TUCCCCAAAIIIIAAAoUSIABQKNlsz0sAgAoArnOGAEC2b6eKbE8AoCKHNZibIgAQjCNnQQABBBBAAAEEEChPAQIABADKc+bSawQQQAABBBBAAAEECiVAAKBQstmelwAAAQACANm+a3pWewIAPWu8s7pbAgBZcdEYAQQQQAABBBBAoMIECAAQAKiwKc3tIIAAAggggAACCCCQpwABgDwBAzucAAABAAIAgb2dKvJEBAAqcliDuSkCAME4chYEEEAAAQQQQACB8hQgAEAAoDxnLr1GAAEEEEAAAQQQQKBQAgQACiWb7XkJABAAyDsA8KMf/UgbbbSRr7n3r3/9S4899ljGthdccEHGNm4Nzj///JyP5cAvCRAAkNTW1qZPP/1Uixcv1urVqzVs2DANHz5cAwcOVCQS6bHThgBAjx16bhwBBBBAAAEEEEBAEgEA72lgKaEB0dGqjw2SZH5vspg3CCCAAAIIIIAAAgggUNECBADCMrwEAAgAuM7Fp556ShMmTMg4V82i/u67756xnWlwySWX6Oyzz87Y1rL4w0BGpOI06HEBgHg8rqefflr33XefHn30UX388cdauXJlWu2amppkGGCLLbbQ1KlT9Z3vfCf5757yIgDQU0aa+0QAAQQQQAABBBBIJ0AAwHteEADgfYMAAggggAACCCCAQE8TIAAQlhEnAEAAwHUuEgAIy9u0pP3oMQGAZ555RrfeeqtmzpypZcuW5YRuqgHssssu+u53v6sf//jH6tevX07nKZeDCACUy0jRTwQQQAABBBBAAIFCCBAAIABQiHnFORFAAAEEEEAAAQQQKF8BAgBhGTsCAAQACACE5d0Yzn5UfADgv//9r04//XTdf//9gY7AoEGDZLayOO6441RVVRXoucNyMgIAYRkJ+oEAAggggAACCCBQCgECAAQASjHvuCYCCCCAAAIIIIAAAuEVIAAQlrEhAEAAIO8AwCOPPKJJkyb5mtNmQfTCCy/M2JYtADISFatBxQYATFn/iy66SNddd53a29sL5mm2B/jNb36j/fbbr2DXKNWJCQCUSp7rIoAAAggggAACCIRBgACA9yiwBUAYZil9QAABBBBAAAEEEECgmAIEAIqp7XUtAgAEAFznh98tAEzZ9COPPNLXnD7qqKN0yy23ZGxLACAjUbEaVGQA4K233tK3v/1tffDBB8VyTFYCuPbaayuqGgABgKJNHy6EAAIIIIAAAgggEEIBAgAEAEI4LekSAggggAACCCCAAAIlFCAAUEL8L1yaAAABgLwDAOeff36y1Lmfl6kU8Nhjj2VsSgAgI1GxGlRcAODRRx/VQQcdJFMBoNiviRMn6t5771VjY2OxL12Q6xEAKAgrJ0UAAQQQQAABBBAoEwECAN4DRQWAMpnIdBMBBBBAAAEEEEAAgcAECAAERpnniQgAEABwnULPPvusdt1114xTzCxqmkXVTK9Vq1Zpo402UlNTk2fTaDSqeDye6XT8vDgCFRUAmD59uqZNm6bOzs7i6KW5yujRo/Xggw9q8803L1kfgrowAYCgJDkPAggggAACCCCAQDkKEADwHjUCAOU4q+kzAggggAACCCCAAAL5CBAAyEcvyGMJABAAcJ1Pb7zxhsaNG+drvj3++OPac889Pdua/dZNtYBMrwEDBmj58uWZmvHz4ghUTADggQce0IEHHqgwVJfYYIMNNG/ePA0ZMqQ4o1igqxAAKBAsp0UAAQQQQAABBBAoCwECAN7DRACgLKYxnUQAAQQQQAABBBBAIEABAgABYuZ1KgIABABcJ9DixYs1YsQIXxPMPNX817/+VePHj0/b/v7779cPf/hDmSoAmV6jRo3Su+++m6kZPy+OQEUEAN5++23ttNNOvuZfcVil3XffPVk5o7q6uliXDPw6BAACJ+WECCCAAAIIIIAAAmUkQADAe7AIAJTRZKarCCCAAAIIIIAAAggEIkAAIBDGAE5CAIAAgOs0Wrdunerq6nxPs5qaGp1wwgnJhdYtt9xSra2tevPNNzVnzhz95S9/8X2eHXfcUS+88ILv9jQsqEDZBwBaWlq08847y4QAwvYy2xFcf/31YeuW7/4QAPBNRUMEEEAAAQQQQACBChQgAOA9qAQAKnDSc0sIIIAAAggggAACCHgKEAAIywQhAEAAwHMubrjhhlq4cGFR5+shhxyiO++8s6jX5GKuAmUfADjssMNCPZ/MXDdzvhxfBADKcdToMwIIIIAAAggggEBQAgQACAAENZc4DwIIIIAAAggggAAClSFAACAs40gAgACA51w0C5N33313UefrDTfcoJ/85CdFvSYXq8wAwMsvv6ztt99elmWFdohNyOadd95RbW1taPvo1jECAGU3ZHQYAQQQQAABBBBAIEABAgDemFQACHCycSoEEEAAAQQQQAABBMpCgABAWIaJAAABAM+5aBbjjz/++KLO19dff13jxo0r6jW5mKtAWVcA+Pa3v61//OMfOQ/v8OHDZc4xefJkjRkzRkOHDlWfPn20bNkyLVmyRHPnztXf//53PfLII8ktL3J9XXXVVfrZz36W6+ElO44AQMnouTACCCCAAAIIIIBACAQIAHgPAgGAEExSuoAAAggggAACCCCAQFEFCAAUldvjYgQACAB4zsWPPvpIm222mTo7O4syZ0eNGpV8GjoSiRTlelwko0DZBgCeeeYZ7bbbbhlvMF2D6upqnXHGGTrnnHN8PZlvtskwVStyDRsMHjxY77//vnr37p1Tf0t1EAGAUslzXQQQQAABBBBAAIEwCBAA8B4FAgBhmKX0AQEEEEAAAQQQQACBYgoQACimtte1CAAQAMg4Fw899FDdddddGdsF0YDy/0EoBnqOsg0A7LvvvpozZ07WGDvssINuvvlmjR8/Putj77jjjuST/MuXL8/62F//+tfJ0EE5vQgAlNNo0VcEEEAAAQQQQACBoAUIAHiLEgAIesZxPgQQQAABBBBAAAEEUU2oewAAIABJREFUwi5AACAsI0QAgABAxrn4yiuvaLvttiv4PupDhgzRggULVFdXl7FPNCiaQFkGAJqbmzVo0KCsK1ecdtppuvTSSxWLxXIGXrp0qQ488ECZCgTZvEzwwGwpUE4vAgDlNFr0FQEEEEAAAQQQQCBoAQIA3qIEAIKecZwPAQQQQAABBBBAAIGwCxAACMsIEQAgAOBrLponky+//HJfbXNpZEr+z5gxQ/vvv38uh3NM4QTKMgBwzz336OCDD85KZZdddtFTTz2laDSa1XHpGputM7beemu1tLT4Ppd5DyxatEgjRozwfUypGxIAKPUIcH0EEEAAAQQQQACBUgoQAPDWJwBQytnJtRFAAAEEEEAAAQQQKIUAAYBSqKe7JgEAAgC+5mI8HtekSZP05JNP+mqfbaNf/OIXuuSSS7I9jPaFFyjLAMBhhx2mO++807dOQ0ODTKWLzTff3PcxmRreeuut+vGPf5yp2Rd+fuONN+rYY4/N6phSNiYAUEp9ro0AAggggAACCCBQagECAN4jQACg1DOU6yOAAAIIIIAAAgggUGwBAgDFFne7HgEAAgC+56LZ1/x73/ueHn/8cd/H+Gl48skn68orr8yr7Lqf69AmJ4GyCwCYsIrZTmLFihW+b/h3v/udzDwM+jVlyhTNmjXL92n322+/rNr7PnGBGhIAKBAsp0UAAQQQQAABBBAoCwECAN7DRACgLKYxnUQAAQQQQAABBBBAIEABAgABYuZ1KgIABACymkCdnZ363//9X11zzTVZHZeucV1dna6//nr96Ec/yvtcnKBgAmUXAFi4cKE23HBD3yBjx47V66+/LlOCP+jXJ598kuyLCSX4eW200Ub68MMP/TQNRRsCAKEYBjqBAAIIIIAAAgggUCIBAgDe8AQASjQxuSwCCCCAAAIIIIAAAiUTIABQMvqUCxMAIACQ01x86aWX9Mtf/lIPPPCALMvK6hz19fXJMuennXaaRo4cmdWxNC66QNkFAF544QXtvPPOvqHOO+88XXjhhb7bZ9twzz339L11Rm1trdra2rK9RMnaEwAoGT0XRgABBBBAAAEEEAiBAAEA70EgABCCSUoXEEAAAQQQQAABBBAoqgABgKJye1yMAAABgLzm4rvvvqs5c+YktwV45plntGzZMiUSiS+cs6qqSubJ5j322EN77bWXvvnNb2rw4MF5XZeDiyZQdgGAmTNn6oADDvANZAIDO+64o+/22TY021uccsopvg8zWxc0Njb6bl/KhgQASqnPtRFAAAEEEEAAAQRKLUAAwHsECACUeoZyfQQQQAABBBBAAAEEii1AAKDY4m7XIwBAACDQuWgW/5uamrR8+XKZhf+BAweqX79+gV6DkxVVoOwCAH/4wx903HHH+UYy87V///6+22fbcNasWZoyZYrvw9544w1ttdVWvtuXsiEBgFLqc20EEEAAAQQQQACBUgv0pACA2TEty+J/IgBQ6hnK9RFAAAEEEEAAAQQQKLYAAYBii7tdjwAAAYCwzEX6EU6BsgsAXHrppTrrrLN8adbV1am1tdVX21wbzZs3L6sKA0899ZR22223XC9X1OMIABSVm4shgAACCCCAAAIIhEygJwUAcqEnAJCLGscggAACCCCAAAIIIFDOAgQAwjJ6BAAIAIRlLtKP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aekSAggggAACCAQqkHz6vz6in/1tqDb/en1u57akWw6R6vpKW+8vmXP6KcZsSvevWiY9ea303SukMROzv/wdpyzXYzc2UwUge7r8j7CkWG1E+5zQX5vuVKtEp6UVn3TqwUubtHp5EUIZlhStjmivo/pqzF71stotrVoR18xLV2jl4oSiOW8NQQAg/8kRzBkIABAA8D2TmpqadNBBB+mxxx7zfYxbw4022kjmSelhw4b5OteMGTN05JFHauXKlRnbEwDISJRNg7IMAFx88cU677zzsrlP/fWvf03O76BeuVTNePzxx7XnnnsG1YWCn4cAQMGJuQACCCCAAAIIIIBAiAUIAHgPDgGAEE9euoYAAggggAACgQiYp/+32adBJ987zPeT+6kXbl4i/WGqdNwMqaGfFG+XquqkmM/nxO4/Tepol/7nd9nf0n+fb9OVUz5VZ7uVc/+zvypHJAW6twEYP6lBu/+4jyIJqTNu6enbW/TaP1vzeALfh2/y6f+IBm0c036nNaqhf9dq//svrNOc33WvweW8CwEBAB8jUJQmBAAIAGQ10eLxuM455xxdfvnlWT3d7LzIDjvsoD/96U/acssts7r2+++/n1ygffnllz2PIwCQFWumxmUZANhll11knsL3+5o6daruv/9+v819tVu9erXGjRuX1VYAp59+ui677DJf5w9DIwIAYRgF+oAAAggggAACCCBQKgECAN7yBABKNTO5LgIIIIAAAggUS6CzQzry2oHa/Yi+OV9y5SfSrYdIx90vPfpbaf7j0u4/kXY+3N8pZ50rrfxYOvwWf+2drczC/5UHLNb8p9tUVZPzim/2F+aILgEror7DIppyeqP6DquSKSi89L0OPXT5aN6BAAAgAElEQVTlSq1pKmAVAPP0f1VUuxzcW+P3q5fVIXV0WnryxuZk+f9YXnsQEAAIy/QmAEAAIKe5aEqlX3LJJbr77rtlQgF+Xqbk/wUXXKD999/fT/O0bdra2nTSSSdp+vTprucgAJAzb7oDyy4AsHbtWvXt29f3vDRtzXweMWJEoHDmZLNnz9bkyZN9n9dsW/D888/7bl/qhgQASj0CXB8BBBBAAAEEEECglAIEALz1CQCUcnZybQQQQAABBBAotIAVl3oPiuqsx0Zq0IZVOV+u2QQADpUOvl66+YfShuOk5mXSCTPk66n8medILYulw27O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IADglbm4RT8+//xzvfHGG3rwwQf11ltvpdTHO++8Uz/96U81dOhQ1/VuuOEG/f73v3ddPtWCw4cP16uvvuqqWufOnbVmzRpXZfNQiABAHpD9egoCAH4dOfqNAAIIIIAAAgggkA0BAgCJFQkAZGOW0QYCCCCAAAII+EGgvtbWXse20QVTe6qkrfcX1L/4b43uOnWFqjbYCqTx+AA/jAl9bC0BAgCtJd/8vAQACAB4ZS622A/btnXXXXfp8ssvl/nczXHKKafo7rvvVo8ePdwUd8rsscce+uijj2Tuvs/2UVFRob59+6q+vt5V04MHD9aCBQtclc1DIQIAeUD26ykIAPh15Og3AggggAACCCCAQDYECAAkViQAkI1ZRhsIIIAAAggg4AcBZ+nClk6f1E3DzmmvoCc2921ZbkNFWA+cv0qfzqpWUXH210P8MF70MZcCBAByqZtK2wQACACkMl9areytt96qsWPHujr/9ttvL/P4AvO6dOlSV3VMoSlTpujCCy90Xd5twbPPPluPPPKI2+I6/fTTNX36dNflc1yQAECOgf3cPAEAP48efUcAAQQQQAABBBDIVIAAQGJBAgCZzjDqI4AAAggggICfBCJhW207B3Th33po15+0keXBO+vrqmw9PX6tnv/zOhb//TS5fNVXAgBeGS4CAAQAvDIXE/bD3P3fv39/ff3110n7a+7ib2ho0EUXXaSpU6cmLR8t0LFjR+fO+969e7uuk6zgiy++qCOOOCJZsS1+bh57MGrUqJTq5LAwAYAc4vq9aQIAfh9B+o8AAggggAACCCCQiQABgMR6BAAymV3URQABBBBAAAE/CphHAey8d4nOu6+7eg8uVg42HE6bpb7a1luPbNA/xq5WpEGeDCikfXFU9JAAAQCvDAYBAAIAXpmLSfuRyi4Aa9as0auvvqqTTjopabuxBU488UQ9+eSTKdWJV/j777/X0KFDtXjxYtftmfBCeXm5evaMrru7rpqrggQAciVbAO0SACiAQeQSEEAAAQQQQAABBNIWIACQmI4AQNpTi4oIIIAAAggg4GMBEwIY8pMynTO5u7rtGPLEQntdta33n9yo6VesVn1tRIEgW//7eIp5vOsEALwyQAQACAB4ZS4m7cesWbN02GGHJS1nCixatEhdunRRt27dnN0AUjnMdv1nnnlmKlW2Kmt2LLj00kt13333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EgCoq92wYQMefPBBzJgxA6JEQLxXRkYG7rrrLqXPBg0axNsd28dGICUFAOvWrcNll12GX375JTYqMbQSmQBeeumllMoGQAFADAeBTUiABEiABEiABEiABGoCAacCAMFCLwSoyEM/Y8aMxoMHD/7M5/O1rQnQuEYSIAESIAESIAESIAESIAESqAkEZFmOPvjgg9Oefvrpn1ys16nzX3Tp1PGvj5ZXX1s53PWR+U4FAKKdaqtvY+X0N8oE4Nb5b8RD5WT0qL2nf265ZSkpAFBXvHPnTsyZMwfvv/8+Pv/8c5SUlDg+v1lZWYpj9sorr8SvfvUr1K1b13FbGlYKgZQTAMyfPx+//vWvITIAVPXVv39/TJ8+HeKcp8JFAUAq7CLXQAIkQAIkQAIkQAIkUAkEzAQAYiij9P/q/RPEAF999VXrXr16fSZJUk4lzJNdkgAJkAAJkAAJkAAJkAAJkAAJVDGBf//73+/ffffd37oc1qkAwG0JADXtv5FT3Szq304E4CTa38zGqtSAm/T/+vIGdiIAsR1mKf8dR72ntABAe2CPHDmiiAC2bNmCvLw87Nq1S3k8ePAgGjdujJycHDRt2lT5E6nSe/XqlVIR0i4/vMlonlICgHHjxuH2229HOByuNtbt27fHBx98gHbt2lXbHBI1MAUAiSLJfkiABEiABEiABEiABFKMQDwCAIGiIguAeL569erTzzjjjI8lSaqfYpy4HBIgARIgARIgARIgARIgARKoUQQmT548/4YbbljoctGxOP/FEGZOQXn0pAAAIABJREFUcP19MxFAVQkAtNkBzAQATp3/2rWYZUJQ2WgfnT633LoaIwBweYBpnnwEUkYAMGvWLAwdOjQh5Sni3aaWLVtixYoVyM7Ojreram1PAUC14ufgJEACJEACJEACJEACyU0gIWUAVDHAhg0bLmjbtu0sABnJvWzOjgRIgARIgARIgARIgARIgARIwIjAJ598suRXv/rVRy7pOHX+i26totyNxACJiP43ct67zQCgdfrrywFoHf/qfPWP2uwFbiP/tRkTtFtjlg3AcvsoAHB5umlebQRSQgCwfv169OjRA4cPH642kPqBL7zwQohyBMFgMGnm5HYiFAC4JUZ7EiABEiABEiABEiCBGkTArQBAoNFG/utfSzt27Li8WbNmkwD4axBHLpUESIAESIAESIAESIAE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Sn+n99wIAMxS/5tF/+s5aDkasdNuW1zp/7Vf7CHLcj6AbBeHospMRTR07969q2y8RA1EAUCiSCr9eE4AEIlEkJ2djf379zsG8fzzz+MPf/iDY3unhoMGDcKcOXOcmuPyyy93Ze+440oypACgksCyWxIgARIgARIgARIggVQiEE8ZAPX3A62jX3vvuAwAAJTXd911V/2nn376P5mZmZenEkiuhQRIgARIgARIgARIgARIgASSiUBBQUHB73//++lTpkzZ7mJe1eH8V0UB+lT6Rq+1znkjIYCRk99pJgAnjn8zYYJ+DZUd/S+2lCUAXBzsSjelACChiD0nANi2bRtatWrlGELnzp2xdu1aiBT8ib527typzEWIEpxcJ598MjZv3uzENClsKABIim3gJEiABEiABEiABEiABJKbgNMsAHqhgD76X6xSKwTQP9eKAZTnW7duvbVFixaPSZIUTG5EnB0JkAAJkAAJkAAJkAAJkAAJeIvAmjVr1l955ZXvb968ucjFzJPB+W8UUW+Udt+ps96NIMBpn2Zz1Dr99RkAxDboRQHqPaNH7T11C40yLrjY3mOp/ZgBwBU2Z8YUADjj5NDKcwKAZcuWoWfPng6XBzzyyCN4/PHHHdu7Nezbty++/PJLR83S09NRXFzsyDYZjCgASIZd4BxIgARIgARIgARIgASSnIBTAYBYRrxlAET744QAn3zySZe+ffu+HgwGT05yTpweCZAACZAACZAACZAACZAACSQ9gWg0GpkwYcKnt9566xIXk7WKJLdKO2+Wsl51dIsp2EXCG0XOW0X+O0n/bxbxb3Xf6D2jsbT3tEIA/XOzdWuZ6J+rr7WP6jbGnf5f+6WeAgAXnw6nphQAOCXlyM5zAoDZs2fjyiuvdLQ4YSQEA927d3ds79bwX//6F+655x7HzUTpgqysLMf21WlIAUB10ufYJEACJEACJEACJEACHiKQqDIA6u8JZpkATsgCIAQBN954Y72XXnrpn3Xr1mVJAA8dGk6VBEiABEiABEiABEiABEgguQgcOHBApPx/d+rUqTsczixex78YxkgEoL2ndYSr9vroeDNHulXkv5v0/24d/07GNcoCYJQBQF2zEQczAYWWq7qVFAA4PNTVZkYBQELRe04A8Prrr2PUqFGOIRw4cAANGjRwbO/WcM6cORg0aJDjZj/88AM6derk2L46DSkAqE76HJsESIAESIAESIAESMBDBKo1C0B5ZgFfbm7uTa1bt35UkqQ0D7HjVEmABEiABEiABEiABEiABEig2gl8991360TK/61btzpN41yVzn/Bxyo9vlVK/XjS/8fq+Dcb0yr630kGAC0H9bnRo/aeerYoAKj2T5nNBCgASOgOeU4A8NRTT+HBBx90BCEjIwNFRW7Kszjq9jijFStWuMowsHDhQvTq1cv9QNXQggKAaoDOIUmABEiABEiABEiABLxIIF4BgFizNupf/1r7nmEWAFUEMHPmzDMuv/zyV4LBYGsvguScSYAESIAESIAESIAESIAESKAqCUQikcj48eM/GTly5FKH47px/IsujerOm90zivxX+7ASAGgzAmjT/+ufG71WnfXaxwgAo/t2ggB9G32WASuhglnKf/19LQ8tXyOm6pYmxPmvflFXOpVlOR9AtsNDU6VmGzduRLdu3XDw4MG4xu3cuTOGDRsWVx9uGj/66KNuzGlrTcBzAoA33ngDI0eOdLSvIvJfZACozGvt2rU488wzHQ+xbt06dOzY0bF9dRpSAFCd9Dk2CZAACZAACZAACZCAhwjYCQC0vxPoywWor7WPZiUAnAgBfJdcckntCRMm/KlJkya3SpIU8BBHTpUESIAESIAESIAESIAESIAEqozApk2bNt95550ffvTRR3scDGrl+BfNrZzMViIAsxIAquNb7duJAEDr4DeKtjdz6tvdtxIEWLV1IgBwEvmvF0Zoeev52e2F0fsOtr/MpOILfTILAMREhQhg6NChEE7MeK7bb78d//nPf5CWxkyD8XCshraeEwDMmzcPAwcOdIyqsLAQtWrVcmzv1vCjjz7CpZde6rhZQUEB6tev79i+Og0pAKhO+hybBEiABEiABEiABEjAYwTsRAB6x7/2twMj57/6vpEYwCgLgLAT99X3fG+88UaH66+/fkxmZua5HmPJ6ZIACZAACZAACZAACZAACZBApRE4cuTIkZdffvmT+++/f42DQdw6/kWXZtHoZjXrzZz9al9OnP/66PpYo/9Vh36sTn+tIMAs5b9eqBBv9L+WudF+1awMAOqhPnr0KEaMGIGpU6c6OOfmJueeey6mT5+O5s2bx9UPG1cpAc8JANasWYMuXbo4hrRhwwa0bdvWsb1bw3HjximfHyeXECIIQYJXLgoAvLJTnCcJkAAJkAAJkAAJkEASEIhFACCmrTr41efae24yAVQ4/tVyAKoYYOXKlUO6dOnygN/vb5wEnDgFEiABEiABEiABEiABEiABEqgWArIsy5999tnyW2655fPt27cX20yiMhz/Yki7aHazlPfaNP+qjVnqf7PIe7tIf7v3rUQB+jHNShHoI/6N1uU27X+VpP/XfmlP6hIA+oP9/PPPY/To0QiHwzF/8LKzs/HOO++gT58+MffBhlVKwHMCgP3796Nhw4aOIQlhy7XXXuvY3q3h8OHDMWnSJEfNTjnlFGzatMmRbTIYUQCQDLvAOZAACZAACZAACZAACXiEgJ0A4LjfCjSZA61KAKht7LIAqNH/+scKUcDgwYPrjx079u6cnJzrAfg9wpTTJAESIAESIAESIAESIAESIIGEENi6dev2e+6558Pp06fn2XQYr+NfdB9Lyn+1ndNoeCfOfzunvJXDP9YMAGalB2Jx/GtZaPmYMdbfd/La1fnyTAkA/aoWLlyIq6++Grt27XK1YK1xIBDAM888g7vvvjvmPtiwygh4TgAgyNSuXdtxJP0VV1yB2bNnVwrQ4uJiCNHL4cOHHfU/aNAgvP/++45sk8GIAoBk2AXOgQRIgARIgARIgARIwEME7EQATssAiCU7if5XbYxKAhxXDkDNBjB+/PjTr7nmmsczMzOdp1Xz0AZwqiRAAiRAAiRAAiRAAiRAAiSgJVBUVFQ0bty4z/70pz+tikajZs59O6e/6NJtank7EYBZJgAnAgA7539lZQCwyxBgFvVvNF+9IMBs3Sp7LS/tflhF/xvtm5O9Nv0QeVYAIFa0c+dODBs2DF9//XVc/5UQQoLx48crzlpeSUvAkwKAgQMHYt68eY6gBoNB7NixA40bJz7b5eTJk3HDDTc4mocwGjt2LG6//XbH9tVtSAFAde8AxycBEiABEiABEiABEvAYATsBgFiOUxGAvjSAmSDAyPmvZgLQlgWoeJ6enu5fsGDBFWefffaojIyMyquX5rHN43RJgARIgARIgARIgARIgARSh0BJSUnJRx99tOyee+75ZtOmTUa1mZ04gp0KBsyc0FZO61gFAG6c/0YZAPROeiOnvtPof7v+tU5+7bh6Z792TeIQmpUA0L6nHtYqS/9/3Bd6WZbzAWR77SNTWlqqRPC/9NJLcU29c+fOmDlzJtq3bx9XP2xcaQQ8KQAYN24cRowY4RjKTTfdhAkTJji2d2J49OhRnHbaadi2bZsTc8VGpP8XZQC8clEA4JWd4jxJgARIgARIgARIgASShIBeAHDc7wPlc3QqAFDb6h3/4r7W6a99X+vwtyoLoGQHSEtL882dO/eic889d2Tt2rU7JwlDToMESIAESIAESIAESIAESIAEYiZQVFRUOHv27KX33nvvkq1btxa77MhKFKB/z+q1XbS63vlv9NrKSW7lWDdz8Js5651E9dvZmGUcMJqn08h/M4GE2FI9X+097Zbb7ZnL46FR9HtVAKCu+K233sKoUaNQVFTkGoLaoF69epg4cSIGDx4ccx9sWGkEPCkA2LNnD3JychCJCBGSs+vjjz/GxRdf7MzYgdV9992Hf/zjHw4sy0zatWuHn3/+2bF9MhhSAJAMu8A5kAAJkAAJkAAJkAAJeIxAdWQB0Dr7zRz/2qwA+swAvlmzZvXq16/fqHr16p3tMd6cLgmQAAmQAAmQAAmQAAmQAAmIUs1HZs6c+fV99923PD8/P+QCiRunv+jWjeNfa6869I3u6d/TOv+10fHqfX00vdFr1WmfSMe/VV/a95xE/huty04YoefvJvrfaO9cHJMyU0+XANCvdvXq1Rg6dChyc3Ndg1AbSJKEBx54AE888QR8PvFbA68kIeBJAYBg169fP3zxxReOMQrBgLBPRDaK2bNnK58JNwKEu+66Cy+88ILj+SaDIQUAybALnAMJkAAJkAAJkAAJkIDHCCRSAKD+vmBXDkCfEcAqE8AJzn9NRgHfxIkTu19xxRW3ZmVlnecx7pwuCZAACZAACZAACZAACZBADSRQUFBQMHXq1MUPPvjgqoKCgrAFAitHv9rMzMYuktwqIt0skt1J1L9VFgArEYBVmv9ECQLMov7N5uUm8j8po//VL+jKYfF6BgD1xB84cECpdT537ty4/vMhIrCnTJmChg0bxtUPGyeMgGcFAKI8hXCqu7mECGDBggXo0KGDm2bH2S5evBgXXXSR66wYn376KQYMGBDzuNXRkAKA6qDOMUmABEiABEiABEiABDxOwG0ZAO1vCGpb7aP+ub4kgP61VgxgJwQwEwP4nn/++TOGDRt2Q5MmTfr4fL50j+8Jp08CJEACJEACJEACJEACJJBiBLZu3bpj+vTpyx9++OE1hYWFVo5/q5W7if53EvkvxtKLARIhANBHy7t1/sfr9K+KyH+jLAgqT7uU/0b7aCfaiOkTkVIZAFQC0WgUY8aMUf5k2YlQxpjdySefjBkzZuCcc86JCS4bJZSAZwUAQpTiJgOASq1JkyY4//zzY4YoBAQFBQWu2w8aNAh+v991u+psQAFAddLn2CRAAiRAAiRAAiRAAh4mUB1ZAPRlAJyUAtCXBThBEHDeeefV/fvf/35Rly5dBmZlZZ2lzXjo4f3h1EmABEiABEiABEiABEiABDxIQET7f/HFF6vHjh27+tNPP93rYglOnJqxOJGdRv6LqRo5uK3uGUXMa4UAZmn/rSLz1bIA+kc3AoFERf6r89eysRIBqHbaR/1z9Ug42UsXx+eYaUoKANTlffjhh0o2gFicoGofGRkZGDt2LG6++eaYALNRwgh4VgCQMALsyJQABQA8HCRAAiRAAiRAAiRAAiQQE4GqygIgJmfk+FezAlhlANA7/43EAMcJAn73u981u+OOOwZ27NjxkszMzJYxkWEjEiABEiABEiABEiABEiABEnBBoKSkpGT58uU/TJo0afUbb7yxORqNap27Thz7RqOZtXPiODYbvzIi/1WHuJ3jXysW0Dr3zRz7bhz+ZuUEtH3ox9eLF/QZDNR16R/FXtmJAFQbdV/d7pmL03eiaUoLAMRyN23apNRAX7NmTVygRo0apdRFT0tLi6sfNo6ZAAUAMaNL/YYUAKT+HnOFJEACJEACJEACJEAClUYg1iwAYkJWJQDU9xNZCsCpGEAIAhRRwD/+8Y/Tr7zyykvbtGnTPxgM1qs0iuyYBEiABEiABEiABEiABEigxhGQZTm6fv36jbNmzVr93HPPrdu/f39pDBCciAOcCgHsnP5iekYCALN7dpH/iYj+N3LyO3H8W9mYRf/bCQCM1qN1/qv89FzMuKrHwYnzX9tHDMfo+CYpLwAQyy0sLMTIkSMxefLkuID17NkT06dPR4sWLeLqh41jIkABQEzYakYjCgBqxj5zlSRAAiRAAiRAAiRAApVCINFZAMQktU5//Wvte2rkvj4TgL4sgD7lv21JgHIBgCoE8DVs2DD46KOPntm7d++ebdq06VGvXr1TKoUmOyUBEiABEiABEiABEiABEkhpAkePHj36/fffb1iwYMGG//73vxs2btxYmKAF2wkBnDiR7QQA+vftxABmEfBG942i//UOd32UvpmjPpYSAFZ9ad9T564vTeBmrWLLrUQA6vvq0XC7d3EfqRohAFApvfjii7jnnntQWhqLAKesl8aNG2PatGno169f3PDZgSsCFAC4wlWzjCkAqFn7zdWSAAmQAAmQAAmQAAkklIATAYAYUGtn9NwqG4BdFgA7AYDW4W/2vCLqX+/8171W2l9++eWNR4wY0f200047Mycnp3OdOnWaJZQqOyMBEiABEiABEiABEiABEkgJAsXFxUW5ublbV69evXX27Nkb33nnnZ269P5267Rz7Bu1dxrxL9raOf21NkYOf/V97XtOIv9jif7XO+KdlAEwS+2vtnXj+LcTKdiJAIxYWfHV74+6104EAXbnyvL9GiUAECQWLVqEq6++Gnl5eTGD8/v9ePrppzF69OiY+2BD1wQ8KQA4ePAgVq5c6Xqx1d2gf//+1T0FV+NTAOAKF41JgARIgARIgARIgARIQE8gHhGA1vEv+o1HCKDNCKCN+o8lI4A+a0BFNoDyOWpf+/r06ZM1fPjwTmeddVbnnJycUxo2bNg6PT29Po8KCZAACZAACZAACZAACZBAzSEQDodLd+3atXvLli27Vq9evW3evHlb5s6du8elw98ImFsRQFUKAPSOfzF/O0e4/n0jx7o+wj6W6H+9c9/M6W/Vtz4LgZ1wQb82PQ/ta/W59tHquXo2KACojP+sCOe/EAEIMUA817BhwzB+/HjUqVMnnm7Y1hkBTwoAFi5ciN69eztbYRJZybLb/y+q3slTAFC9/Dk6CZAACZAACZAACZCA5wnEIwAQizcSAbgVAiSiHICb0gB62xNeX3DBBVmDBg1qffrpp7du1qxZs6ysrOz69etn161bt5Hf70/z/K5zASRAAiRAAiRAAiRAAiRQAwnIsiwfOnTo0P79+w/k5+cfyMvL2//999/nL168eNf8+fP3hcPhqnKQ2I3jVARglwHAKupfnACraH/t+1rHuNbhr963EwEYCQKcOvTd2Fk5/M0yADgVPKg8jLipnyaz/TB63+peXJ/OGpcBQKUlygCIcgCiLEA812mnnYb33nsPHTp0iKcbtrUnQAGAPaOEWVAAkDCU7IgESIAESIAESIAESIAEvEIgkSIAM0GAmupfMNGWBdA7/7UR//rof7tsAGaR/07EAXalBirGPvfcc7POOOOMrObNm9fLzs6ue9JJJ9XLysqqk5mZmRkMBoN+vz8QCASC4h/xXFdCAbIsH8db/1r5NUlnU/HLkMl9JwfNrE8nbWlDAiRAAiRAAiRAAiRAAslIQPgzotFoJBwOR0KhkHgMl5aWRoqLi0MHDhwo3LNnj/K3c+fOo1u2bDm6fPnyg4WFhZEkWEssAgB9G7PXRk5oIyGAPvrf6LWVc9wupb6Z018f2W/32qgMgFWbeKP+rbIAKF/Xys+P2WPF1zeDc1bp0f/qF25lbFmW8wFkJ8GBr9IpTJ48GSNHjkRhYWHM49atWxcTJ07EkCFDYu6DDW0JUABgiyhxBhQAJI4leyIBEiABEiABEiABEiABjxCIRQCg/V0hkaUA3AgAzJz2RkIA26h/AGppAKN+jcQIZnPVChzMnqv89MII7X0jxmb3jvudRy860JxDo73WHlO79z1ypDlNEiABEiABEiABEiABEkhqAokWADh1+gsoRlH/2vtOI+K1jnYnkfdGkfzxOv+17Z3MwShjgdl67Vip76sHLSmi/4/7YlhTBQACwpo1azB06FBs2rQprv8S3H///XjyySfh9/vj6oeNDQlQAFCFB4MCgCqEzaFIgARIgARIgARIgARIIHkIxCIC0LZJRCkA1RluVhJA69iPJRuAlQjAcQaAcqGA3vlv9NqtEED9rcZKUHHc7zk6R79+D53uqfYUUgCQPJ9JzoQESIAESIAESIAESCA1CVS3819QNRIBaB3hWhsrp7ld6n+9U14fzW8nADBy8FsJCYxEAHqhgtV6jNat3tNz09/Xnlankf52ZyGmT0DFl7qaLAAQ5AoKCjB8+HB88MEHMYFUGw0YMABTp05Fo0aN4uqHjU8gQAFAFR4KCgCqEDaHIgESIAESIAESIAESIIHkIeDUWWzmZNaLAcwEAdr7Zg5yOwGAVYS+PvrfqdPfrJ1R5L9eiGDn/BeDVFqiAAAgAElEQVT24nKSDUBrpz63etS+p39u9NrsnvYkUgSQPJ9LzoQESIAESIAESIAESCC1CNg5fJ04js0izfUp6QU5vaPf6J6dGEArDNA6/GPJAGDl8Hf6nlXUv11ZAjfZDaz4qe+ppzNpov+P+8JX0wUAyi7JMsaMGaP8RaPifMR2tWrVCjNmzEC3bt1i64CtjAhQAFCF54ICgCqEzaFIgARIgARIgARIgARIILkIxCICsMsCoP7+YOb4175v5kjXCgKssgDYRfHblQawEhZYCQGczFvr/Nev2YiN9ncbu4wAx/3GY5D+3+m+ak8jRQDJ9dnkbEiABEiABEiABEiABLxPwOvOf7PIeW1Uv5M0/EYR/FaZAcyyADgZyyra30wMIE6akShCva99tHquPbFOhB0JO+GeyACwevVq3HbbbQlbtF1H69atw8GDB+3MLN9PT09HcXFxXH2w8XEEKACowgNBAUAVwuZQJEACJEACJEACJEACJJBcBNw4io0c/2I1Vs5qJ9H/RlHydhkBjEQBVpkA3AgFYs0AoJ+z0bpUXup72tdGz434au9ZPde/pz15bpz9bmyT63RzNiRAAiRAAiRAAiRAAiRQNQTsHP3aWZjZ6u9bvdZH/lu91r6nf+40Ot4sC4AbIUA8Dn+7ccwyE9itT+yL1kZ9rb2v7p1RtgWtvd0euzkjrk+tJwQACxcuRO/evV0vrrobeM2JWt28bManAKAKN8hrZ1eSJP4AVYXng0ORAAmQAAmQAAmQAAmkPAGnIgC9nd7xL0DpHf7qvViEAEZZAOyc84kQBtiNoTrvzUQKRo5/q2wAZoz0PLWvnT5XD6/Zdyg3363c2Kb8h4YLJAESIAESIAESIAESIIFyAm4cu150/uud606i8I0c9m4FAFZp/+0c/nrBgl4IILbO7J76ntGj9p7+ufqBcLrHCf0AUQCQUJzHd+Y1J2olokhE1xQAJIKiwz68dnYpAHC4sTQjARIgARIgARIgARIgAWcEnAoARG+xZAFQ2xlFvVs5y60c7FZlAdyIAIwyA1S2AMBIDKFlpOWsZaa/r98Pq/1RT4KdE9/ufWcnilYkQAIkQAIkQAIkQAIkQAJ2wgAnKeK1NkYR6G4i/2ON/rdytttF5jtx+ls5+s36j1UAIE6llRhAfd/oUXtP/1x72p3sa8I/HRQAJBzpsQ695kStRBSJ6JoCgERQdNiH184uBQAON5ZmJEACJEACJEACJEACJOCcQGWLAOyc3mZCALtSAHbOejsxQHUJAOx4iJ3TZ1iwy7ig3W2zbA36E+HG4e/G1vnJoyUJkAAJkAAJkAAJkAAJeJuAnaNfuzqnzmEjx7/ox8rhr38/Ean/VWe5NqLe6LkTIYBdVoBYI/7Nov3V+yoXJ45/JyILdT+d7qV2XyrtpFMAUGloAa85USsRRSK6pgAgERQd9uG1s0sBgMONpRkJkAAJkAAJkAAJkAAJOCfgJkW8lXPZymlt5PQ2u6cKApxkAbATAThx8ltlFND2b/Vc/55VdgOnAgAznmJnrQQB6s5XhhBAO7bzE0ZLEiABEiABEiABEiABEkgdAvE6/QUJOwdyPCIAo2h/dUy9I9zutd7Brnfka6PxrYQAsb7nJAOB3RqcOP+1fNSTarcH+hNtt6eV9gmgAKDS0FIAkGC0nhQAbN26FRMmTEgwisrv7tFHH638QRI4AgUACYTJrkiABEiABEiABEiABEjgGIFYswCIHuyi0/UOb7WN1kludE8vAHDijHfqzNfa2bUxEhmYOfyN5qwXA9itX/u+EV/tXjl5ru1Df+adRvY7teNnigRIgARIgARIgARIgARqCgGnQgAzO/19q9fxRP8bCQKcOM3NnP9mTvlEOPljTfvvZD3iXGrt1NdWj9r39M+157zanP/HfdmTZTkfQHYyfgIXLlyI3r17J+PULOfktSjqJAfsSQFAkjNNmelRAJAyW8mFkAAJkAAJkAAJkAAJJBcBN1kAjvuNQSMA0N6PJRuAXihg5kyPtzSAk6wA+iwE2jHNnptlLqgsAUA8zn8rhz6d/cn12eRsSIAESIAESIAE/p+9+4/dJavrAz4XZPeuC9UVgdYfrBGy2IrG0LRahVVXWw1qY7Q2FtMKEhsFWxstqaAWsUJTaeofpJCqAZUKrcYosUq3FEhZRWMEtUSMiyK4/tou2+0Wdpe7y+63OZfv0HPPzsw5Z56ZeWbmee0/9/t9njMz57zOPA/c+3mfMwQIbEtgKBiQKxT3hQC6VqO3xeygkxb529fSNiWF8rZNSQCg9pEAuccFdO0oMLQLQOl4Yo+un1PD9o7LhTTi49K7tDQgcvDdbQeAgwn7TyAAMCmuAMCknPs6mQDAvubTaAgQIECAAAECBFYlUBMCGNpefqj4HwbcFsTjn9MiecnvuaJ8bmV/+n7XSv+hNn27AAy93jfmPpf29ZI/4zbtjTU0T/HNV1r0L223qhtbZwgQIECAAAECBAhMKFBT2B2z+j+39XzXbgBTBwBKiv+5Yn2u2D9mtX/ar5IAQJj6riBE+3r8Z99raZv4dsqFOia89bpPJQAwI7EAwKS4AgCTcu7rZAIA+5pPoyFAgAABAgQIEFidQFeBtzQY0LUiPbcTQLrqv6TwH7fJhQBKivpd56gp/Jds+58bV7gRuoIR7eslf8Zt0p/bG61mftObU/F/dR9XHSJAgAABAgQIEDiSQGkIYC0BgJrHAHQV2btW+ncFAGp3BEh3G+i7TroLQG3hvy8gEW6fXOAibRPfcqXzO+ttKgAwI68AwKS4AgCTcu7rZAIA+5pPoyFAgAABAgQIEFidQGmxv6+gnBb8Q7uuEEBa+G/b5QrlXe/3PRKgq/g/FAgobd+1wv+QEEA69vj3Pr+u1+PX0p+7fu97rW9uV3ez6hABAgQIECBAgACBlQjkAgG5VeJ9W813Fadzxezctv+BrKuA3re6Plf8H7sTwNDW/kM7EBxS/I/H3t466Y4KbZv41srNX67trLepAMCMvAIAk+IKAEzKua+TCQDsaz6NhgABAgQIECBAYJUCh4QAunYBCIOcOwSQK8qXbPefCwCk1+gq+tcGAVqbodX/Q7soxLZDP6fvtTfe0Kr+Naz4X0MfVvkh1SkCBAgQIECAAIErBHIF+CW4hvqQKyDnVqF3bfsfxjT11v9xcT1XhE+38C8NAsxZ+O/a6SB1Gvo9fq+9Z2pW+R/lPtxEAODXf/3Xm6/5mq9Z4oM46TXuuOOOSc934icTADjxG2Bo+AIAbg4CBAgQIECAAAECiwjUbBWftp0rBBAG3lXoT3cF6HssQE2Bv+TRAkN9yQUB2rGkfY9fb38eeq29GYZ2XkjbxDfQ2gIACv6LfLxdhAABAgQIECCwa4FjFGEPKf6HyTgkADBHCGDMYwD6Cvs1Owi0AYS+3Qhyq/9by9wuCbF5n306L/GHpiYUMPuHbRMBgNkVXGALAgIAW5ilI/VRAOBI8C5LgAABAgQIECBwagKH7AIQrLpCAOlrJbsCxAXy9rzxa0OF9pJHAwyt6j80BJAW94d+T8cW/x575nYD6LNPX2/v5zUFABT/T+1bxngJECBAgAABAvMJLB0CmCMA0FWYzhW2u1bAt0XzoJ0roJc8BqB0Bf+Shf+hEEQ77qE/4/fau7K2yL/0PfexT48AwHxfJM48rcAmAwB333138453vGNaiQXOdtNNNy1wlekuIQAwnaUzESBAgAABAgQIEMgIzBkCGCpkx+8NrZAfWvk/FBIo2SFgKBjQt/I/t+q/LwAQpqEv6BC/1/7c9Wf82tDP6XvtLVBafC9t58NFgAABAgQIECBAYK8CpYXe3Lb/wSdtkyv6x8fMsfK/KyAw9CiA0vdKHyeQCyj0vd+65AISqXlu54Wue7hkXhe99wUAFuV2sQMENhkAuOWWW5obb7zxgGEf59Czs9L/rTpO/9KrCgCsYx70ggABAgQIECBA4GQE1hYCCPAlK+v7ivFDuwLUFv1Lr9HV375xxK93/dy+NvRn/F76c9fv7c1cWtwvbXcyHxIDJUCAAAECBAgQOCmBkqJK6erxXAG6LxAQF7oDft8q//i92uJ67jEA6U4AQzsD5NrW9i1u3zf+9vWuP+PX0p+7fm9v8NJ5XfQDIQCwKLeLHSAgAHAAXu2hAgC1YtoTIECAAAECBAgQOCmB2gBAwEmPiX/PbWGfrv5vz9cW0dPflwoDTL3qP7ezQTzOrp9T59S17/325h0zr/GNLwRwUl8DBkuAAAECBAgQIHAuMFfxP5w+Lep3vVZS+G+PS4vqfa+XrPpv29Su5C8JEcTX73sEQcmY4jZDdvF76c9dv7c3/yqL/1f8xe/s7Oz2pmke7+NKYKUCAgALTowAwILYLkWAAAECBAgQIEBgmwK1xeKhAED87xMlYYA0END1e0kIIG7TtXK/5LVDVvwP9bE16Qo5xO+V2F3x7z+ZMEbaNr075yryz3XebX669JoAAQIECBAgQGBJgZIC/pj+DJ03t2V86S4AXcX/0Nc5Vv+XhgJygYCulf99YYKhXQDicXaNt8uhfS3+c+jn9L34Plht8f+Kv9QJAIz57DpmQQEBgAWxBQAWxHYpAgQIECBAgAABAtsVWFMIoP03jtrCf1/7kuJ/e2xfCKBvh4C+a3aNIX0t/j3+d51ccOKKfwNaaQgg7eN2Pxl6ToAAAQIECBAgsAWBuQr/YexLFP/b6+RCAPH7fcGA2u32+1blT/V6SX/i8adjLLFp79G+sMXQPNbO7+KfB48AWJzcBUcKCACMhBtzmADAGDXHECBAgAABAgQIEDhJgWOGAAJ4XExPf6/dGWCokD9UzM8dNyaUkBtb+37Nn3Hb9Of25u2az9LV+aXtTvKDYtAECBAgQIAAAQK7FSgJEpSuFi9d+R8wa7f+b4855DEAQ6v3D3mvpOCf63c8vj6f+PWhn9P34pt39cX/K/6yZweA3X7x7GVgAgALzqQAwILYLkWAAAECBAgQIEBg2wJDRd/ScEDcruvn3Or2rm3yh16rLciXFPhL2pRct/23mr5gQ/x+/O86OaMr/g0o2QGgtug/daF/6vNt+xOl9wQIECBAgAABAscQKCni1/artOgfzpu27QoCDL2WruxvzznH6v+hYn3fDgDxMSVt4vbxWPpe7xpv7JqGJVLzIf903mvmtfaemay9HQAmo3SimQUEAGYGjk8vALAgtksRIECAAAECBAgQ2L7A1CGAIJIWtNPXugreXSv+2+Nqtt0fW8wfe1zfTgVp3+Pfu4wOCQHE50vvyJICfUmb7d/pRkCAAAECBAgQIEDg4QKl4YGudiWF/3DFXPG/bdO3K8CSQYDaAn/J6v94fOlYhsYe2+V2V2hndswK/9J7YLHPjwDAYtQudKCAAMCBgDWHCwDUaGlLgAABAgQIECBAgEDHM+VblJpwQNo2FwII1+ha6d/3+pS7AqSBgtrif9zH9Fzpe32/t6+n401f75qLvl0XcvM2ZaF/ynP5EBIgQIAAAQIECBCYQmDKQm5NIbkkCDAmBDBULC9ZZV9SnD90R4B094Ku84W5za3+b9sM/Rm/l/7c9Xt8T21i5f/D/kLnEQBTfC84x4wCAgAz4qanFgBYENulCBAgQIAAAQIECOxHoK+gu0QIICjmwgB9K+1zBfjc1v0lxf+4f0PnS9vlxtX1fvpvPn3F/r7ARXpHlhTqS9rs5043EgIECBAgQIAAAQJXCpQEB5bYASD0qqugHr/etRtASRH+0DBA6fFpX2tW/A+FJNrztjM3FLpI7+9NFf/bvyReHoQAgO+qlQsIACw4QQIAC2K7FAECBAgQIECAAIF9CawtBND+28fQ6v+0Ta7gX/p+zXm72savdf089Fp7Vw3topC2ie/EMfNYeycLDdSKaU+AAAECBAgQILCEQEkxv6QfU+8AEK7ZtcV/+npXm76if3tsyar70gJ+abuaa8dtS8bbzk9XICA+vqtdOrc181hyXyzSxiMAFmF2kQkEBAAmQCw9hQBAqZR2BAgQIECAAAECBAh0CIwpHudWo3etYk+L212/p6v+Q3fjAn76e+l7JSGAoXPXBBLi87Q/D73WTkmu+J8zT88zdLMr5vsqIECAAAECBAgQOGWBktBA7Q4AwTMt5ne9liv4t8f0rfJP3+/bar+0sJ+2Gzp/aTAhHXcuCBG3H/o5fS+9hzdZ/I//0mgHgFP+WtrG2HcdAHjOc57TXH/99UUz8ba3va15y1vekm37Az/wA9k2fQ1e/OIXjz72GAdeuHDBPzYdA941CRAgQIAAAQIECHQL1Gz5H58hV5AeGwJo//0jDQOU/H5IICC+bldgoOv99LWuvg+9dsW/9ZyHHfpea+275mtMiKPm8+DvcDVa2hIgQIAAAQIECCwpUFLML+lPTfF4aDv6oW3thwrhJVvn94UCxoYAgksuKNDVJn0t/r3r5/a1rj/7Xotfb+evZo7iOZ/qHim5j0a1sQPAKDYHHUFg1wGAUNR/xjOeUcT6spe9rPne7/3ebNutreLPDmiggQDAIXqOJUCAAAECBAgQIDCLwFQhgNC5rsJ//HouGFCyM0BXGKDvtaHV+6WBgbb/Q+3jNul4S3Y/aCc259fVLr4pSor1JW1mudGclAABAgQIECBAgMAKBEoKwkvuABBIuor7fa/3rcQfer0kPFBz3lyf2/dL/ozbtLfHUMgivYXGBgNWcCt+tAsCAKuZCh3JCAgAnAMJADz8ThEA8P1BgAABAgQIECBAYJUCS4YA4n/jGCqO94UB0mJ/e76Sgn5X21xIID1m6Pf4vdJxXvFvPgMhirRdeyPZAWCVHymdIkCAAAECBAgQWEigpKCf60pNEfnQHQBCX9KCfO61ruJ8fExJgb+r/RxF/76dDtrrx3+mP5f8Hs9lzbzl7oGjvS8AcDR6F64UEAA4BxMAePidIwBQ+WnSnAABAgQIECBAgMByAmsMAYTR5wr+bZuanQHiY3LBgbRt3/W6Xk/7P/R713vt7KdzU/MogPQOsgPAcp8pVyJAgAABAgQIEFifQElgoGQHgDCyri3/49dLHwnQVTQfeixAX+G+vXbJYwFK2sZtcj93jTsdV4lZfMeMLfCXzPFq7kwBgNVMhY5kBHYdAPjv//2/N1/2ZV9WdBP8wA/8QPOSl7wk29YjALJEGhAgQIAAAQIECBAgsIzA2BBA6F2uSD20/X98fO4xAG3bmmBAaTggPnfXMUPvp2PIbf3fNebUscY0vUOmKPRPcY5l7lxXIUCAAAECBAgQOFWBKYq9tYXmkl0ASov/Yd6Giv3t+7lAwNhdAuLz1/ajr+/p6+29mQtMxPdw7Zx0XWMTnwkBgE1Mk042TbPrAMBrXvOa5tnPfnbRRD/3uc9tXv3qV2fbCgBkiTQgQIAAAQIECBAgQGA5gaVDAGFkuWJ5LhQwFAZoz9+31X/N+3Hb3M8144rbDv2cvhffFSXF+pI2y91prkSAAAECBAgQIEBgeYGSwEBfm5LCfxjRUPE/fr/vUQBtm9KCfEnxPz5nLkzQdf2h19IxtbOa2wEgtUqP67o7xgYDlr/TCq8oAFAIpdnRBXYdAHjxi1/chJX9Jf+FnQLe8pa3ZJsKAGSJNCBAgAABAgQIECBAYFmBKUMAoeddq/9LXh8KBhwSCqjZPaDtZ0nIoKttPM7SXRBSm67f+14ber3mLhIWqNHSlgABAgQIECBA4NgCJYX9oT7WFJanCAJ0bfsf+tcXChgbBojPWXqOoX6075X8GbdJfy75PZ2vmjk69v1YfH0BgGIqDY8ssMkAwNvf/vbmi77oi7J0N910U/PmN7852+6DH/xgc/311zd33XXXYNtHPOIRzYMPPpg9314aXLhwwT8i7WUyjYMAAQIECBAgQGDvAnOGAIJdLhRw6K4A7TVKCvdduwPkju96Px5Xaf9LLOJ7rWteSv6eVdJm7/e08REgQIAAAQIECBAIAiVhgSV3AYj7dGgAoD3XFMX+oZBC2uf2zupa9Z+ad9nm5mSXxf8r/jJ4dnZ2e9M0j/cZJbBSgU0GAH73d3+3eepTn1pE+ta3vrX5ki/5ksG2P/iDP9iE3QJy/33SJ31Sc+edd+aa7eZ9AYDdTKWBECBAgAABAgQInIZArmhcGxJI2+dCAPG/h5QW1NNifnuO0iBAV/vcOcb0s+uYK/795/wWGzKL78LcXHWd+zTuYqMkQIAAAQIECBAg8P8FcoXm0HJM8T89bugxAH3vzbErQNuvkkBAPIbc4wla0dw2/0O7JaTn6LtPd1v8v+IvaQIAvqdWLrDJAMCf//mfN5/yKZ9SRHvDDTc0P/uzP9t87ud+bmf7n//5n2+++Zu/uQm7AOT+e/KTn9y85z3vyTXbzfsCALuZSgMhQIAAAQIECBA4HYFcYXnM+7VBgKGt83OPAoj/TaU2HNAeW3uN9JpX/LtOtPtBSQAiPba982rDFzV3bG5Oa86lLQECBAgQIECAAIElBEoK+0P9qC0yT/kYgNCvvgJ9yXtdwYHc+WpX9/e1j/s39HP6XjsXte7xHB4650vcl9lreARAlkiDlQhsMgBw6dKl5uLFi8WEV111VfP85z+/+Zt/8282f/Wv/tXmvvvua9797nc3N998c/MzP/Mzxef5G3/jbzS/8Ru/Udx+6w0FALY+g/pPgAABAgQIECBwwgKHFJxLtq0vKYb37QIQpqW2SD+0o0Dtufqu3/V6/Frpz+1tV+LYdYsq6J/wB9fQCRAgQIAAAQIEOgVKisdT7gQwtCNA6GDt6v/2mNrjDi38d/U1fi39uev3vtfiicrNT+79zdz2AgCbmaqT7+gmAwBh1p74xCc2t91226IT+KxnPav56Z/+6UWvecyLCQAcU9+1CRAgQIAAAQIECBwsMHUIIHRo7t0A4muUPEZgijZD10zHXBJ8aCeuz7+kwF/S5uAbxAkIECBAgAABAgQIbECgtHhc+qz62t0ASh4PUFKon6pNmLLcueI2pT+n7dpbI+d/6PsbuAX/fxcFADY1XSfd2c0GAEIx/vWvf/2ik/eqV72q+bZv+7ZFr3nMiwkAHFPftQkQIECAAAECBAhMIpArJI95fygEEDo99AiA+P0pdwgoOW8uLNB1jr7xpK93/d73WjuxOfvcDXDo8bnze58AAQIECBAgQIDA3AK54nHu+rVb0tcW/8P1SwIAcbvcFv+5tmPe7zqmr+/p612/t+65+Tn0/dz8ru59AYDVTYkO9QhsNgAQivHPe97zFp3Yd73rXc1Tn/rURa95zIsJABxT37UJECBAgAABAgQITCaQKxSPfb92N4AwoKFwQMl7uSJ+7ftxn0qDC+3E5IIQ6XjTCc25526AQ4/Pnd/7BAgQIECAAAECBOYWyBWQc9efMgAQrtVV7I9fLwkD5Fbn597vul7fMbm+pWMq+b2rTToPuXnLvZ+b19W+LwCw2qnRsURgswGAP/7jP26e9KQnNR/5yEcWmdQnP/nJza233tpcuHA6/8YiALDIreUiBAgQIECAAAECBJYQyP1FJvd+6GNXm1wRvGTL/NqdAOK+jAkNdB1f0892vnJj7zPrO772PiiZs9pzak+AAAECBAgQIEBgSYFDC8W540seC5Ar+gePocJ//H5aqB9675AgQNd5+/rZzufQ7gfxnI8xrTl+yftr8msJAExO6oQzCWw2ABA8vumbvql53eteNxPNlac9te3/L/9L1SmlHRa5i1yEAAECBAgQIECAwNEFckXjse/niuE1BfaSov7lv7Kca44JEMTHd52r7/12AnPjTY/vmvicde5mOfT43Pm9T4AAAQIECBAgQGAJgVzBOdeHpXcBCP0pKfR3tavZQSB3nfj90p9by5JgRJd7bq5y7+fmcvXvCwCsfop08Fxg0wGA3/7t326e9rSnNWdn836nPP7xj2/e//73NxcvXjypG0cA4KSm22AJECBAgAABAgRORyBXOM69H6RKdgPoajdVECA+d+nW/aXt0n7niv2lFvEdVmI8dEceevzp3O1GSoAAAQIECBAgsAWBQ4s8xwwBBN+xgYCuY3M7EvS9H5+rnfOSVf8l9rk2ufe3cA8W9VEAoIhJoxUIbDoAEPz+xb/4F80P//APz0YZFsG/4Q1vaL7ma75mtmus9cQCAGudGf0iQIAAAQIECBAgcLBASQF5bJtcQXyooJ4LCIx5P3dMwCxpk7br+r3vtXjCSlyHJvjQ4w++eZyAAAECBAgQIECAwAwChxaR5wwBhOGOLczXhgPia+Wu2U5DrtDfZ5Mzz72fusxwW6zrlAIA65oPvekX2HwA4MEHH2y+7Mu+rPkf/+N/zDLPL3zhC5uXvexls5x77ScVAFj7DOkfAQIECBAgQIAAgYMFcsXk3PuhA31tckGA9NiSInxNm5q2Q33pGmPJ2NrJKTEccjx4kp2AAAECBAgQIECAwE4ESgrSYag1Be+a4nlJQb6mTU3brnHV9D2+BUocp2qzk1vvo8MQANjVdO56MJsPAITZufPOO5tv+IZvaN761rdOOln/9J/+0+bf/bt/1zzykY+c9LxbOZkAwFZmSj8JECBAgAABAgQIHCRQUqA+pE1JsbyvWH/Fv7EUrtRfS+E/7XvfJJXYHjTBDiZAgAABAgQIECCwM4GS4nQY8tJBgPSaXQX+kqL/0Hm6xpULArTTX+I2VZud3XIfHY4AwC6ndZeD2kUAIMzMRz7ykea7vuu7mle84hUHT9TFixebV77ylc1znvOcg8+15RMIAGx59vSdAAECBAgQIECAQLVASSH6kDa1QYAr/n1loPhf2q40ZJCer+T3Fjvnk3s/N2mHHp87v/cJECBAgAABAgQIHEugpPCc61vtYwDC+bqOGSqol77XV+hPrzmmXetQWvjvG2fqWTIHJW1y87TZ9wUANjt1J9fx3QQA2pl75zvf2fzQD/1Q8wu/8AvN2Vnd99A111zT/ON//LhnB58AACAASURBVI+bF7zgBc2nfuqnntzNkA5YAODkbwEABAgQIECAAAECpydQUmAuaRPkpno0QNe5Sov5aR9Kj8tds70zhiwOdTq9u8+ICRAgQIAAAQIECJQJlBZ/agMBuTBAruA+tphfelzQyfUxFSyxmqpN2extuJUAwIYn78S6vrsAQDt/73nPe5qbb7758mMBfvVXf7W54447moceeuiK6f24j/u45vrrr2+++Iu/uPnSL/3S5iu+4iuaxz3ucSd2C/QPVwDArUCAAAECBAgQIEDgZAVKitclbQLgIUGAruPnLOoPnbu9GWrGE99ApV5DN90U5zjZm9rACRAgQIAAAQIEVi9QUojODSJ3jtLHApQU2kt3Awh9rgkPlLTvahPb5Bxyx7fnKjlPbk52874AwG6mcvcD2W0AIJ25UPy/6667mjvvvLMJhf/HPvaxzSd8wifsfoIPGaAAwCF6jiVAgAABAgQIECCwC4GSgnNJm4BRWzgfU4zPHVP7fl+/p1j5P2Syi5vHIAgQIECAAAECBAjMLFBanJ56J4B2WFMX9UtCB+HateNJp2EKt5mndp2nFwBY57zo1cMFTiYAYPLrBQQA6s0cQYAAAQIECBAgQGCHAocW+FOS2uJ5V/uS13LF/tCvkvP0tRt6vR1zqd3QbTPFOXZ4WxoSAQIECBAgQIDAjgVKC9RDBLlz1BbRS4rzuUBA6O+YNu04S3cv6HPJmeSus+NbrmxocQDgiU3TPLLsMK0ILC7w/vMrPrj4lV1w9QICAKufIh0kQIAAAQIECBAgsKRAaSF6inY1uwWMLeKXHheMa/qTzkmpR24upzpP7jreJ0CAAAECBAgQIHBMgdIi9VAfS85RW0wvCQCEPpW0K2nTjq82qNDlUuLR1/dj3guru7a/lK1uSnRo8Jvw7Kz0ww/yhAQEAE5osg2VAAECBAgQIECAQLlA6b95lLYLV67dFaDvmJpC/RQBgFZtqrGWz4KWBAgQIECAAAECBAi0AjU1rlzbmmDAXG3DuBT+V3h/1/zFb4Xd16VTEzgTADi1KS8arwBAEZNGBAgQIECAAAECBE5VoPTfPkrbBcdc25oC/9D5aor/h/Sr697IjfFU7yfjJkCAAAECBAgQIDBWIFfUT887trheU/AP16xZ6d/Xvu17zRhL25a2GzsvuzvOX+Z2N6X7HtDWAgB333138453vGNzk3LTTTdtqs8CAJuaLp0lQIAAAQIECBAgcCyBmn8DmbJtbRgg+Ex5TOtdM6ahPhxr/lyXAAECBAgQIECAwNYFagvZufZLBQSC+yF9Sectd662fWm7rd8Xk/e/9i9/k3fACQnUCGwtAHDLLbc0N954Y80QV9F2axstCACs4rbRCQIECBAgQIAAAQJbEaj5t5CatmH8ufZjHiFw6HlLjk/nLjeOrcy1fhIgQIAAAQIECBBYm8CYonbumKmDAK3ZIddN3XPnitvXtF3b/K6iP/5Ct4pp0IlSAQGAUqnD2gkAHObnaAIECBAgQIAAAQIENiNQ8+8iNW0DQK793O+X9KFronL92szk6igBAgQIECBAgACBlQqMKXCXHJNrc+j7gTN3jpS8pn1N25VO7Tq65S9165gHvSgUEAAohDqwmQDAgYAOJ0CAAAECBAgQIEBgawI1/z5S07Z1KD0m1y73fu314nkqPffW5lZ/CRAgQIAAAQIECKxVYEzBu/SYknZTtUl9S87bHlPTdq3zuLp++cvd6qZEh4YEBACWuT8EAJZxdhUCBAgQIECAAAECBFYpUPNvJTVt48GWHlfaLpy7pu2YvqxysnSKAAECBAgQIECAwE4ExhTCa44pbVvaLmWvPa62/U6meZlhjP3L4TK9cxUCiYAAwDK3hADAMs6uQoAAAQIECBAgQIDA6gVq/92ktn0LUHvc3O1LJqa2DyXn1IYAAQIECBAgQIDA1gWmLmyPOV/NMTVt07mpPba2/dbvhaP131/WjkbvwmMEBADGqNUfIwBQb+YIAgQIECBAgAABAgR2L1D7byi17VPAMcePOaa97iHH7n7yDZAAAQIECBAgQIDADAKHFsTHHD/mmHboY44dc8wM1Kd1Sn+5O6353vxoBQCWmUIBgGWcXYUAAQIECBAgQIAAgc0KjPn3lDHHpEBTnCOcc6rzbHYCdZwAAQIECBAgQIDAigWmKJof8xxTXHvF07P+rvkL3/rnSA8jAQGAZW4HAYBlnF2FAAECBAgQIECAAIHdCIz995Wxx3XBTXmuvolZ4hq7uSkMhAABAgQIECBA4OQF5i6ET3n+Q851yLEnf5PMAeAvbnOoOudsAgIAs9FecWIBgGWcXYUAAQIECBAgQIAAgd0KHPLvLYccmwOd89y5a3ufAAECBAgQIECAAIFygTmL6oee+9DjyxW0HCXgL36j2Bx0LAEBgGXkBQCWcXYVAgQIECBAgAABAgRORmCqf3+Z6jxj4I957TH9dQwBAgQIECBAgACBNQgcs1g+xbWnOMca5uGk+uAvbyc13dsfrADAMnMoALCMs6sQIECAAAECBAgQIHDyAlP/u8zU5zv5CQJAgAABAgQIECBAYKUCUxfmpz7fStlOo1v+Ynga87ybUW4tAPDHf/zHzWte85rV+L/0pS9tHnjggWx/BACyRBoQIECAAAECBAgQIEBgCYEl/91myWstYecaBAgQIECAAAECBNYusGTRfclrrd199/3zl7vdT/G+Bri1AMDa9K+99trm3nvvzXZLACBLpAEBAgQIECBAgAABAgS2IODffbYwS/pIgAABAgQIECBAoExAEb/M6eRb+Yvgyd8C2wIQADhsvgQADvNzNAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIE1CwgArHl29O1hAgIAh90UAgCH+TmaAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAwJoFBADWPDv6JgAw8T0gADAxqNMRIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQWJGAAMCKJkNX8gJ2AMgbDbUQADjMz9EECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE1iwgALDm2dG3hwkIABx2UwgAHObnaAIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJrFhAAWPPs6JsAwMT3gADAxKBOR4AAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQGBFAgIAK5oMXckL2AEgbzTUQgDgMD9HEyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEFizgADAmmdH3x4mIABw2E0hAHCYn6MJECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIrFlAAGDNs6NvAgAT3wMCABODOh0BAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBFQkIAKxoMnQlL2AHgLzRUAsBgMP8HE2AAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBgzQICAGueHX17mIAAwGE3hQDAYX6OJkCAAAECBAgQIECAAAECBAgQIECAAAECBAgQILBmAQGANc+OvgkATHwPCABMDOp0BAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBFYkIACwosnQlbyAHQDyRkMt/sk/+SfN/fffnz3Jf/gP/yHbZk0NLly44LtsTROiLwQIECBAgAABAgQIECBAgAABAgQIECBAgAABAkcRUDQ7CruLjhUQABgrt+/jBAD2Pb9GR4AAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUCYgAFDmpNVKBAQAVjIRK+uGAMDKJkR3CBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEjiIgAHAUdhcdKyAAMFZu38cJAOx7fo2OAAECBAgQIECAAAECBAgQIECAAAECBAgQIECgTEAAoMxJq5UICACsZCJW1g0BgJVNiO4QIECAAAECBAgQIECAAAECBAgQIECAAAECBAgcRUAA4CjsLjpWYGsBgLvvvrt5xzveMXa4RzvupptuOtq1x1xYAGCMmmMIECBAgAABAgQIECBAgAABAgQIECBAgAABAgT2JiAAsLcZ3fl4thYAuOWWW5obb7xxc7Nydna2qT4LAGxqunSWAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBgJgEBgJlgnXYeAQGAeVzTswoALOPsKgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgSmFBAAmFLTuWYXEACYnfjyBQQAlnF2FQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJTCggATKnpXLMLCADMTnz5AgIAyzi7CgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAIEpBQQAptR0rtkFBABmJ758AQGAZZxdhQABAgQIECBAgAABAgQIECBAgAABAgQIECBAgMCUAgIAU2o61+wCAgCzE1++gADAMs6uQoAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQGBKAQGAKTWda3YBAYDZiS9fQABgGWdXIUCAAAECBAgQIECAAAECBAgQIECAAAECBAgQIDClgADAlJrONbuAAMDsxJcvIACwjLOrECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIEJhSQABgSk3nml1AAGB24ssXEABYxtlVCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECEwpIAAwpaZzzS4gADA78eULCAAs4+wqBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBKYUEACYUtO5ZhcQAJid+PIFBACWcXYVAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAlMKCABMqelcswvsNQDwpCc9qfmH//Af9vq99rWvbf7wD/8w6/uc5zynuf7663vbvfSlL20eeOCB7HkEALJEGhAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBYnYAAwOqmRIeGBPYaAPiKr/iK5r/+1//aO/Sv/MqvbG6++ebszfG2t72tecYzntHb7tprr23uvffe7HkEALJEGhAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBBYnYAAwOqmRIeGBAQAhu8PAQCfHwIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQKnKyAAcLpzv8mRCwAIAHQJXLhwwXfZJj/ROk2AAAECBAgQIECAAAECBAgQIECAAAECBAgQIDClgKLZlJrONbuAAIAAgADA7B8zFyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIENiogADARifuVLstACAAIABwqp9+4yZAgAABAgQIECBAgAABAgQIECBAgAABAgQIEMgJCADkhLy/KgEBAAEAAYBVfSR1hgABAgQIECBAgAABAgQIECBAgAABAgQIECBAYEUCAgArmgxdyQsIAAgACADkPydaECBAgAABAgQIECBAgAABAgQIECBAgAABAgQInKaAAMBpzvtmRy0AIAAgALDZj6+OEyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIzCwgADAzsNNPKyAAIAAgADDtZ8rZCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE9iMgALCfuTyJkQgACAAIAJzER90gCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIERggIAIxAc8jxBAQABAAEAI73+XNlAgQIECBAgAABAgQIECBAgAABAgQIECBAgACBdQsIAKx7fvQuERAAEAAQAPC1QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKBbQADAnbEpgVMNALz4xS9u3vnOd2bn6t/8m3/T/LW/9td621177bXNvffemz3P2dlZts2aGly4cMF32ZomRF8IECBAgAABAgQIECBAgAABAgQIECBAgAABAgSOIqBodhR2Fx0rsLUAwG233da89rWvzQ73Mz/zM5tv/MZvzLY7tMHLX/7y5oEHHsie5kUvelG2zZoaCACsaTb0hQABAgQIECBAgAABAgQIECBAgAABAgQIECBA4FgCAgDHknfdUQJbCwCMGqSDqgUEAKrJHECAAAECBAgQIECAAAECBAgQIECAAAECBAgQILBDAQGAHU7qnockALDn2R0/NgGA8XaOJECAAAECBAgQIECAAAECBAgQIECAAAECBAgQ2I+AAMB+5vIkRiIAcBLTXD1IAYBqMgcQIECAAAECBAgQIECAAAECBAgQIECAAAECBAjsUEAAYIeTuuchCQDseXbHj00AYLydIwkQIECAAAECBAgQIECAAAECBAgQIECAAAECBPYjIACwn7k8iZEIAEw/zffcc09z//33N9ddd930J1/ojAIAC0G7DAECBAgQIECAAAECBAgQIECAAAECBAgQIECAwKoFBABWPT06lwoIAEx3TzzwwAPNj/3YjzX/6l/9q+bLv/zLm9e+9rXTnXzhMwkALAzucgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAqsUEABY5bToVJ/AXgMAoRj/7ne/u/mLv/iL5n/9r//VfPCDH2w+6ZM+qXn84x/fXH/99c2TnvSkyW6Ks7Oz5vWvf33z/d///c173/vej533lltuaZ7+9KdPdp0lTyQAsKS2axEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECKxVQABgrTOjX50CewoAXLp0qXnd617X/Jf/8l+aN73pTZeL/n3/PeUpT2m+7uu+rvnu7/7u5rGPfezou+OXf/mXmxe96EXN7/zO7zzsHJ/7uZ/bvPOd72we+chHjj7/sQ4UADiWvOsSIECAAAECBAgQIECAAAECBAgQIECAAAECBAisSUAAYE2zoS9ZgT0EAB588MHmJ37iJ5qXvOQlzW233ZYdc9zgiU98YvMzP/Mzzed//udXHff2t7+9+Z7v+Z4mrPIf+u9Hf/RHm2/91m+tOvcaGgsArGEW9IEAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQODYAgIAx54B168S2HoA4AMf+MDllfy5QvwQyqMe9ajm5S9/efOd3/mdWbs77rijee5zn9v84i/+YrZtaPDUpz61ede73lXUdk2NBADWNBv6QoAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgcCwBAYBjybvuKIEtBwB+7/d+r/mqr/qq5o/+6I9GjT096Nu//dubV77ylYPneuihh5pnPvOZzc0331x8zRBOePrTn17cfg0NBQDWMAv6QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgcGwBAYBjz4DrVwlsNQBw1113NU972tOa973vfVXjzTX+lV/5leaLvuiLBpvdeeedzV//63+9ef/735873eX3v+mbvqn5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BAgQIECAAAECBAgQILAHAQGAPcziCY1hawGAZz7zmc0b3/jG7Ay96lWvar7t276tt92lS5ea66+/PhsmyF6ooEEILbzvfe9rrr766oLW62giALCOedALAgQIECBAgAABAgQIECBAgAABAgQIECBAgACB4woIABzX39UrBbYWAHjpS1/afN/3fV92lE984hOb3//9328uXrzY2/aHfuiHmrA1/9z/ha3/l7jOlOMQAJhS07kIECBAgAABAgQIECBAgAABAgQIECBAgAABAgS2KiAAsNWZO9F+by0A8O53v7v57M/+7KLZ+o7v+I7mFa94RW/bO++8swlBgXvvvbfofGMahQDCbbfd1nzyJ3/ymMOPdowAwNHoXZgAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQGBFAgIAK5oMXckLbC0AEEb0WZ/1WZdX9+f++8RP/MTmXe96V/Npn/ZpvU2f//znN6985Stzpxr9/ste9rLmhS984ejjj3WgAMCx5F2XAAECBAgQIECAAAECBAgQIECAAAECBAgQIEBgTQICAGuaDX3JCmwxAPCiF72o+df/+l/3ju3Rj350853f+Z3Nd3/3dzfXXXfdoMEHPvCB5vM///Ob9773vVmr2gZf/MVf3LzlLW9pHvGIR9QeevT2AgBHnwIdIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQWIGAAMAKJkEXygW2GAB43/ve1zz5yU9uHnzwwSsG+vEf//FN2Pb/BS94QdWW++GxAl/4hV/Y3H333eVwmZZh14G3v/3tzad/+qdPds4lTyQAsKS2axEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECKxVQABgrTOjX50CWwwAhIE861nPal7/+tdfHtPFixebb//2b2++53u+p3n84x8/aqZvvvnm5qu+6qseFioYc7LP/uzPbt74xjdutvgfxiwAMGbmHUOAAAECBAgQIECAAAECBAgQIECAAAECBAgQILA3AQGAvc3ozsez1QDAb/3WbzV/62/9reZbv/Vbmxe+8IXNp3zKpxw8Uz/90z/d/LN/9s+a8FiAsf993dd9XfPjP/7j2UcPjD3/UscJACwl7ToECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJrFhAAWPPs6NvDBLYaAAgDueOOO5rHPe5xk87q//2//7f54R/+leb6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IAAgALDogHMzAgQIECBAgAABAgQIECBAgAABAgQIECBA4PQEBAAEAE5vVB7wiQQADojr0scWEAAQADj2GHR/AgQIECBAgAABAgQIECBAgAABAgQIECBA4MgCAgACAEcegsveXgBgWW93W1RAAEAAYNEB52YECBAgQIAAAQIECBAgQIAAAQIECBAgQIDA6QkIAAgAnN6oPOATCQAcENeljy0gACAAcOwx6P4ECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAkQUEAAQAjjwEl729AMCy3u62qIAAgADAogPOzQgQIECAAAECBAgQIECAAAECBAgQIECAAIHTExAAEAA4vVF5wCcSADggrksfW0AAQADg2GPQ/QkQIECAAAECBAgQIECAAAECBAgQIECAAIEjCwgACAAceQgue3sBgGW93W1RAQEAAYBFB5ybESBAgAABAgQIECBAgAABAgQIECBAgAABAqcnIAAgAHB6o/KATyQAcEBclz62gACAAMCxx6D7EyBAgAABAgQIECBAgAABAgQIECBAgAABAkcWEAAQADjyEFz29gIAy3q726ICAgACAIsOODcjQIAAAQIECBAgQIAAAQIECBAgQIAAAQIETk9AAEAA4PRG5QGfSADggLgufWwBAQABgGOPQfcnQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEjiwgACAAcOQhuOztBQCW9Xa3RQUEAAQAFh1wbkaAAAECBAgQIECAAAECBAgQIECAAAECBAicnoAAgADA6Y3KAz6RAMABcV362AICAAIAxx6D7k+AAAECBAgQIECAAAECBAgQIECAAAECBAgcWUAAQADgyENw2dsLACzr7W6LCggACAAsOuDcjAABAgQIECBAgAABAgQIECBAgAABAgQIEDg9AQEAAYDTG5UHfCIBgAPiuvSxBQQABACOPQbdnwABAgQIECBAgAABAgQIECBAgAABAgQIEDiygACAAMCRh+CytxcAWNbb3RYVEAAQAFh0wLkZAQIECBAgQIAAAQIECBAgQIAAAQIECBAgcHoCAgACAKc3Kg/4RAIAB8R16WMLCAAIABx7DLo/AQIECBAgQIAAAQIECBAgQIAAAQIECBAgcGQBAQABgCMPwWVvLwCwrLe7LSogACAAsOiAczMCBAgQIECAAAECBAgQIECAAAECBAgQIEDg9AQEAAQATm9UHvCJTikA8EO/KuKf+I0392X/tz8S8Zf+2M1dz5VunYAAgADArRu0HpgAAQIECBAgQIAAAQIECBAgQIAAAQIECBC4WQEBAAGAmx1RJ361UwoAnDiVx7t9AgIAAgC3b9R6YgIECBAgQIAAAQIECBAgQIAAAQIECBAgQOBGBQQABABudECd+sUEAE79J+T5riEgACAAcI3h46MECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAXRAQABAAuAvjeOfv8Pf8IxE/5xftfPrWE//2X4z4//7y1tOcQGAJAQEAAYAlxpl7ECBAgAABAgQIECBAgAABAgQIECBAgAABAicsIAAgAHDCw9OjESCwh4AAgADAHsPFqQQIECBAgAABAgQIECBAgAABAgQIECBAgMBdFBAAEAC4i+PadyJwHwUEAAQA7uO4950JECBAgAABAgQIECBAgAABAgQIECBAgACBTkAAQADALwQBAndDQABAAOBujGTfggABAgQIECBAgAABAgQIECBAgAABAgQIELiygACAAMCVB48PEiBwUgICAAIAJzUgPQwBAgQIECBAgAABAgQIECBAgAABAgQIECCwvIAAgADA8qPOHQkQOISAAIAAwCHGlWsSIECAAAECBAgQIECAAAECBAgQIECAAAECt0hAAEAA4BYNV49KgMAGAQEAAQC/IAQIEOwtHkEAACAASURBVCBAgAABAgQIECBAgAABAgQIECBAgMA9FxAAEAC4578Cvj6BOyMgACAAcGcGsy9CgAABAgQIECBAgAABAgQIECBAgAABAgQIXE1AAEAA4Gojx6cIEDg1AQEAAYBTG5OehwABAgQIECBAgAABAgQIECBAgAABAgQIEFhYQABAAGDhIed2BAgcSEAAQADgQEPLZQkQIECAAAECBAgQIECAAAECBAgQIECAAIHbIiAAIABwW8aq5yRAYLOAAIAAgN8RAgQIECBAgAABAgQIECBAgAABAgQIECBA4J4LCAAIANyrX4Gf98MRv+BH7tVXPtqX/ZkfO9qt7+uNBQAEAO7r2Pe9CRAgQIAAAQIECBAgQIAAAQIECBAgQIAAgSYgACAAcK9+GX7xj0b8sp+4V1/5aF/2p7/51+Voj3DfbiwAIABw38a870uAAAECBAgQIECAAAECBAgQIECAAAECBAgMAgIAAgD36pdCAGC5H7cAwHLW7U4C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CBAgQIAAAQIECBAgsLCAAIAAwMJDzu0IEDiQgACAAMCBhpbLEiBAgAABAgQIECBAgAABAgQIECBAgAABArdFQABAAOC2jFXPSYDAZgEBAAEAvyMECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAPRcQABAAuOe/Ar4+gTsjIAAgAHBnBrMvQoAAAQIECBAgQIAAAQIECBAgQIAAAQIECFxNQABAAOBqI8enCBA4NQEBAAGAUxuTnocAAQIECBAgQIAAAQIECBAgQIAAAQIECBBYWEAAQABg4SF33Nv9vB+O+AU/ctxnuC93/5kfuy/f9GS+pwCAAMDJDEYPQoAAAQIECBAgQIAAAQIECBAgQIAAAQIECBxHQABAAOA4I+9Id/3FPxrxy37iSDe/Z7f96W/+dblnX/x4X1cAQADgeKPPnQkQIECAAAECBAgQIECAAAECBAgQIECAAIGTEBAAEAA4iYG41EMIACwlHSEAsJx1u5MAgADA4oPODQkQIECAAAECBAgQIECAAAECBAgQIECAAIHTEhAAEAA4rRF54KcRADgwcHd5AYDlrAUAYv0uYv1YAGDxQeeGBAgQIECAAAECBAgQIECAAAECBAgQIECAwGkJCAAIAJzWiDzw0wgAHBhYAGA54A/vpAOAAMAxx597EyBAgAABAgQIECBAgAABAgQIECBAgAABAicgIAAgAHACw3C5RxAAWM5aB4DlrNudBAAEABYfdG5IgAABAgQIECBAgAABAgQIECBAgAABAgQInJaAAIAAwGmNyAM/jQDAgYG7ywsALGctAGAJgMVHmxsSIECAAAECBAgQIECAAAECBAgQIECAAAECJykgACAAcJID81APJQBwKNkPrysAsJy1AIAAwOKjzQ0JECBAgAABAgQIECBAgAABAgQIECBAgACBkxQQABAAOMmBeaiHEgA4lKwAwHKys3eyBIAlAE5gGHoEAgQIECBAgAABAgQIECBAgAABAgQIECBA4JgCAgACAMccf4vfWwBgOXIdAJazbncSABAAWHzQuSEBAgQIECBAgAABAgQIECBAgAABAgQIECBwWgICAAIApzUiD/w0AgAHBu4uLwCwnLUAgCUAFh9tbkiAAAECBAgQIECAAAECBAgQIECAAAECBAicpIAAgADASQ7MQz2UAMChZD+8rgDActYCAAIAi482NyRAgAABAgQIECBAgAABAgQIECBAgAABAgROUkAAQADgJAfmoR5KAOBQsgIAy8nO3skSAJYAOIFh6BEIECBAgAABAgQIECBAgAABAgQIECBAgACBYwoIAAgAHHP8LX5vAYDlyHUAWM663UkAQABg8UHnhgQIECBAgAABAgQIECBAgAABAgQIECBAgMBpCQgACACc1og88NMIABwYuLu8AMBy1gIAlgBYfLS5IQECBAgQIECAAAECBAgQIECAAAECBAgQIHCSAgIAAgAnOTAP9VACAIeS/fC6AgDLWQsACAAsPtrckAABAgQIECBAgAABAgQIECBAgAABAgQIEDhJAQEAAYCTHJiHeigBgEPJCgAsJzt7J0sAWALgBIahRyBAgAABAgQIECBAgAABAgQIECBAgAABAgSOKSAAIABwzPG3+L0FAJYj1wFgOev/n707j7asrO99/a2GKkrpW1EhooANKCKtRuWIBo29RiUqgidR401OMhKNsTdBozE35mhOzLjGJMcIopjYEZvYEjtEOhWxQUAFFekKpZOiqap9x05tsGTXrpprrTnf/a45H8dwlCZzvs2zf8t/6sNeczsJAAQAxYfOhgQIECBAgAABAgQIECBAgAABAgQIECBAgEBdAgIAAUBdE9nxaQQAHQNvtLwAoJy1AMBXABSfNhsSIECAAAECBAgQIECAAAECBAgQIECAAAECVQoIAAQAVQ5mV4cSAHQlO39dAUA5awGAAKD4tNmQAAECBAgQIECAAAECBAgQIECAAAECBAgQqFJAACAAqHIwuzqUAKArWQFAOdkFd/IVAL4CoIIxdAQCBAgQIECAAAECBAgQIECAAAECBAgQIEBgMQUEAAKAxZy/4nsLAMqR+w0A5azndhIACACKD50NCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAgboEBAACgLomsuPTCAA6Bt5oeQFAOWsBgK8AKD5tNiRAgAABAgQIECBAgAABAgQIECBAgAABAgSqFBAACACqHMyuDiUA6Ep2/roCgHLWAgABQPFpsyEBAgQIECBAgAABAgQIECBAgAABAgQIECBQpYAAQABQ5WA6VHmB469OVu3S3r4CgPYsG67kKwB8BUDDUfEYAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0FcBAYAAoK+z7V4jCggARgSr73EBgACgvql0IgIECBAgQIAAAQIE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AAECBKZFQAAgAJiWWXVOAgQ2LyAAEAD4jBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIDFxAACAAG9RHY48hkz6MHdeVFu+xZr160rYe6sQBAADDU2XdvAgQIECBAgAABAgQIECBAgAABAgQIECBAYE5AACAAGNSH4aBXJYe/cVBXXrTLvuOO/3VZtCMMbWMBgABgaDPvvgQIECBAgAABAgQIECBAgAABAgQIECBAgMCdBAQAAoBBfSgEAOV+3AKActZzOwkABADFh86GBAgQIECAAAECBAgQIECAAAECBAgQIECAQF0CAgABQF0T2fFpBAAdA2+0vACgnLUAIDNrk5mVAoDiQ2dDAgQIECBAgAABAgQIECBAgAABAgQIECBAoC4BAYAAoK6J7Pg0AoCOgQUA5YDn7+Q3AAgAFnP+7E2AAAECBAgQIECAAAECBAgQIECAAAECBAhUICAAEABUMIbljiAAKGftNwCUs57bSQAgACg+dDYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6hIQAAgA6prIjk8jAOgYeKPlBQDlrAUAvgKg+LTZkAABAgQIECBAgAABAgQIECBAgAABAgQIEKhSQAAgAKhyMLs6lACgK9n56woAylkLAAQAxafNhgQIECBAgAABAgQIECBAgAABAgQIECBAgECVAgIAAUCVg9nVoQQAXckKAMrJLriTrwDwFQAVjKEjECBAgAABAgQIECBAgAABAgQIECBAgAABAospIAAQACzm/BXfWwBQjtxvAChnPbeTAEAAUHzobEiAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSAAEADUNZEdn0YA0DHwRssLAMpZCwB8BUDxabMhAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUKWAAEAAUOVgdnUoAUBXsvPXFQCUsxYACACKT5sNCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAgSoFBAACgCoHs6tDCQC6khUAlJNdcCdfAeArACoYQ0cgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEFlNAACAAWMz5K763AKAcud8AUM56bicBgACg+NDZkAABAgQIECBAgAABAgQIECBAgAABAgQIEKhLQAAgAKhrIjs+jQCgY+CNlhcAlLMWAPgKgOLTZkMCBAgQIECAAAECBAgQIECAAAECBAgQIECgSgEBgACgysHs6lACgK5k568rAChnLQAQABSfNhsSIECAAAECBAgQIECAAAECBAgQIECAAAECVQoIAAQAVQ5mV4cSAHQlKwAoJ7vgTr4CwFcAVDCGjkCAAAECBAgQIECAAAECBAgQIECAAAECBAgspoAAQACwmPNXfG8BQDlyvwGgnPXcTgIAAUDxobMhAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUJeAAEAAUNdEdnwaAUDHwBstLwAoZy0A8BUAxafNhgQIECBAgAABAgQIECBAgAABAgQIECBAgECVAgIAAUCVg9nVoQQAXcnOX1cAUM5aACAAKD5tNiRAgAABAgQIECBAgAABAgQIECBAgAABAgSqFBAACACqHMyuDiUA6EpWAFBOdsGdfAWArwCoYAwdgQABAgQIECBAgAABAgQIECBAgAABAgQIEFhMAQGAAGAx56/43gKAcuR+A0A567mdBAACgOJDZ0MCBAgQIECAAAECBAgQIECAAAECBAgQIECgLgEBgACgrons+DQCgI6BN1peAFDOWgDgKwCKT5sNCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAgSoFBAACgCoHs6tDCQC6kp2/rgCgnLUAQABQfNpsSIAAAQIECBAgQIAAAQIECBAgQIAAAQIECFQpIAAQAFQ5mA5VXuD4q5NVu7S3rwCgPcuGK/kKAF8B0HBUPEaAAAECBAgQIECAAAECBAgQIECAAAECBAj0VUAAIADo62y714gCAoARwep7XAAgAKhvKp2IAAECBAgQIECAAAECBAgQIECAAAECBAgQKCogABAAFB04m9UrIACo92fT8GQCAAFAw1HxGAECBAgQIECAAAECBAgQIECAAAECBAgQINBXAQGAAKCvs+1eIwoIAEYEq+9xAYAAoL6pdCICBAgQIECAAAECBAgQIECAAAECBAgQIECgqIAAQABQdOBsVq+AAKDen03DkwkABAANR8VjBAgQIECAAAECBAgQIECAAAECBAgQIECAQF8FBAACgL7OtnuNKCAAGBGsvscFAAKA+qbSiQgQIECAAAECBAgQIECAAAECBAgQIECAAIGiAgIAAUDRgbNZvQICgHp/Ng1PJgAQADQcFY8RIECAAAECBAgQIECAAAECBAgQIECAAAECfRUQAAgA+jrb7jWigABgRLD6HhcACADqm0onIkCAAAECBAgQIECAAAECBAgQIECAAAECBIoKCAAEAEUHzmb1CggA6v3ZNDyZAEAA0HBUPEaAAAECBAgQIECAAAECBAgQIECAAAECBAj0VUAAIADo62y714gCAoARwep7XAAgAKhvKp2IAAECBAgQIECAAAECBAgQIECAAAECBAgQKCogABAAFB04m9UrIACo92fT8GQCAAFAw1HxGAECBAgQIECAAAECBAgQIECAAAECBAgQINBXAQGAAKCvs+1eIwoIAEYEq+9xAYAAoL6pdCICBAgQIECAAAECBAgQIECAAAECBAgQIECgqIAAQABQdOBsVq+AAKDen03DkwkABAANR8VjBAgQIECAAAECBAgQIECAAAECBAgQIECAQF8FBAACgL7OtnuNKCAAGBGsvscFAAKA+qbSiQgQIECAAAECBAgQIECAAAECBAgQIECAAIGiAgIAAUDRgbNZvQICgHp/Ng1PJgAQADQcFY8RIECAAAECBAgQIECAAAECBAgQIECAAAECfRUQAAgA+jrb7jWigABgRLD6HhcACADqm0onIkCAAAECBAgQIECAAAECBAgQIECAAAECBIoKCAAEAEUHzmb1CggA6v3ZNDyZAEAA0HBUPEaAAAECBAgQIECAAAECBAgQIECAAAECBAj0VUAAIADo62y714gCAoARwep7XAAgAKhvKp2IAAECBAgQIECAAAECBAgQIECAAAECBAgQKCogABAAFB04m9UrIACo92fT8GQCAAFAw1HxGAECBAgQIECAAAECBAgQIECAAAECBAgQINBXAQGAAKCvs+1eIwoIAEYEq+9xAYAAoL6pdCICn1FiMQAAIABJREFUBAgQIECAAAECBAgQIECAAAECBAgQIECgqIAAQABQdOBsVq+AAKDen03DkwkABAANR8VjBAgQIECAAAECBAgQIECAAAECBAgQIECAQF8FBAACgL7OtnuNKCAAGBGsvscFAAKA+qbSiQgQIECAAAECBAgQIECAAAECBAgQIECAAIGiAgIAAUDRgbNZvQICgHp/Ng1PJgAQADQcFY8RIECAAAECBAgQIECAAAECBAgQIECAAAECfRUQAAgA+jrb7jWigABgRLD6HhcACADqm0onIkCAAAECBAgQIECAAAECBAgQIECAAAECBIoKCAAEAEUHzmb1CggA6v3ZNDyZAEAA0HBUPEaAAAECBAgQIECAAAECBAgQIECAAAECBAj0VUAAIADo62y714gCAoARwep7XAAgAKhvKp2IAAECBAgQIECAAAECBAgQIECAAAECBAgQKCogABAAFB04m9UrIACo92fT8GQCAAFAw1HxGAECBAgQIECAAAECBAgQIECAAAECBAgQINBXAQGAAKCvs+1eIwoIAEYEq+9xAYAAoL6pdCICBAgQIECAAAECBAgQIECAAAECBAgQIECgqIAAQABQdOBsVq/AzgcmS5a3d77V57a3lpUaCQgABACNBsVDBAgQIECAAAECBAgQIECAAAECBAgQIECAQH8FBAACgP5Ot5sRGJaAAEAAMKyJd1sCBAgQIECAAAECBAgQIECAAAECBAgQIEBgnoAAQADgY0GAQD8EBAACgH5MslsQIECAAAECBAgQIECAAAECBAgQIECAAAECYwsIAAQAYw+PFwkQqEpAACAAqGogHYYAAQIECBAgQIAAAQIECBAgQIAAAQIECBAoLyAAEACUnzo7EiDQhYAAQADQxVxZkwABAgQIECBAgAABAgQIECBAgAABAgQIEJgiAQGAAGCKxtVRCRDYjIAAQADgA0KAAAECBAgQIECAAAECBAgQIECAAAECBAgMXEAAIAAY+EfA9Qn0RkAAIADozTC7CAECBAgQIECAAAECBAgQIECAAAECBAgQIDCegABAADDe5HiLAIHaBAQAAoDaZtJ5CBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgcICAgABQOGRsx0BAh0JCAAEAB2NlmUJECBAgAABAgQIECBAgAABAgQIECBAgACBaREQAAgApmVWWznnHkcmex7dylIW2YLAWa9GVFhAACAAKDxytiNAgAABAgQIECBAgAABAgQIECBAgAABAgRqExAACABqm8lOz3PQq5LD39jpFhafE3jHHf/rgqSQgABAAFBo1GxDgAABAgQIECBAgAABAgQIECBAgAABAgQI1CogABAA1DqbnZxLANAJ6yYXFQCUs57bSQAgACg+dDYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6hIQAAgA6prIjk8jAOgYeKPlBQDlrAUAmVmbzKwUABQfOhsSIECAAAECBAgQIECAAAECBAgQIECAAAECdQkIAAQAdU1kx6cRAHQMLAAoBzx/J78BQACwmPNnbwIECBAgQIAAAQIECBAgQIAAAQIECBAgQKACAQGAAKCCMSx3BAFAOWu/AaCc9dxOAgABQPGhsyEBAgQIECBAgAABAgQIECBAgAABAgQIECBQl4AAQABQ10R2fBoBQMfAGy0vAChnLQDwFQDFp82GBAgQIECAAAECBAgQIECAAAECBAgQIECAQJUCAgABQJWD2dWhBABdyc5fVwBQzloAIAAoPm02JECAAAECBAgQIECAAAECBAgQIECAAAECBKoUEAAIAKoczK4OJQDoSlYAUE52wZ18BYCvAKhgDB2BAAECBAgQIECAAAECBAgQIECAAAECBAgQWEwBAYAAYDHnr/jeAoBy5H4DQDnruZ0EAAKA4kNnQwIECBAgQIAAAQIECBAgQIAAAQIECBAgQKAuAQGAAKCuiez4NAKAjoE3Wl4AUM5aAOArAIpPmw0JECBAgAABAgQIECBAgAABAgQIECBAgACBKgUEAAKAKgezq0MJALqSnb+uAKCctQBAAFB82mxIgAABAgQIECBAgAABAgQIECBAgAABAgQIVCkgABAAVDmYXR1KANCVrACgnOyCO/kKAF8BUMEYOgIBAgQIECBAgAABAgQIECBAgAABAgQIECCwmAICAAHAYs5f8b0FAOXI/QaActZzOwkABADFh86GBAgQIECAAAECBAgQIECAAAECBAgQIECAQF0CAgABQF0T2fFpBAAdA2+0vACgnLUAwFcAFJ82GxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJVCggABABVDmZXhxIAdCU7f10BQDlrAYAAoPi02ZAAAQIECBAgQIAAAQIECBAgQIAAAQIECBCoUkAAIACocjC7OpQAoCtZAUA52QV38hUAvgKggjF0BAIECBAgQIAAAQIECBAgQIAAAQIECBAgQGAxBQQAAoDFnL/iewsAypH7DQDlrOd2EgAIAIoPnQ0JECBAgAABAgQIECBAgAABAgQIECBAgACBugQEAAKAuiay49MIADoG3mh5AUA5awGArwAoPm02JECAAAECBAgQIECAAAECBAgQIECAAAECBKoUEAAIAKoczK4OJQDoSnb+ugKActYCAAFA8WmzIQECBAgQIECAAAECBAgQIECAAAECBAgQIFClgABAAFDlYHZ1KAFAV7ICgHKyC+7kKwB8BUAFY+gIBAgQIECAAAECBAgQIECAAAECBAgQIECAwGIKCAAEAIs5f8X3FgCUI/cbAMpZz+0kABAAFB86GxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJ1CQgABAB1TWTHpxEAdAy80fICgHLWAgBfAVB82mxIgAABAgQIECBAgAABAgQIECBAgAABAgQIVCkgABAAVDmYXR1KANCV7Px1BQDlrAUAAoDi02ZDAgQIECBAgAABAgQIECBAgAABAgQIECBAoEoBAYAAoMrB7OpQbQcAp/9Jcv7bxjvtA/84+fW3jvfupt4689XJ1980/nrHX52s2mX89+/8pgCgPcuGK/kKAF8B0HBUPEaAAAECBAgQIECAAAECBAgQIECAAAECBAj0VUAAIADo62xv8l4CgIV/3AKAqf8oCAAEAFM/xC5AgAABAgQIECBAgAABAgQIECBAgAABAgQITCYgABAATDZBU/a2AEAAMGUjO8pxBQACgFHmxbMECBAgQIAAAQIECBAgQIAAAQIECBAgQIBADwUEAAKAHo71wlcSAAgAejzwAgABQI/H29UIECBAgAABAgQIECBAgAABAgQIECBAgACBJgICAAFAkznpzTMCAAFAb4Z5/kUEAAKAHo+3qxEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJNBAQAAoAmc9KbZwQAAoDeDLMAYGbF3F/43/7nSgFAj8fb1QgQIECAAAECBAgQIECAAAECBAgQIECAAIEmAgIAAUCTOenNMwIAAUBvhlkAIADo8TC7GgECBAgQIECAAAECBAgQIECAAAECBAgQIDCegABAADDe5EzpWwIAAcCUjm6TY/sKAL8BoMmceIYAAQIECBAgQIAAAQIECBAgQIAAAQIECBDosYAAQADQ4/GefzUBgACgxwMvABAA9Hi8XY0AAQIECBAgQIAAAQIECBAgQIAAAQIECBBoIiAAEAA0mZPePCMAEAD0ZpjnX0QAIADo8Xi7GgECBAgQIECAAAECBAgQIECAAAECBAgQINBEQAAgAGgyJ715RgAgAOjNMAsAZlbM/YX/7X+uFAD0eLxdjQABAgQIECBAgAABAgQIECBAgAABAgQIEGgiIAAQADSZk948IwAQAPRmmAUAAoAeD7OrESBAgAABAgQIECBAgAABAgQIECBAgAABAuMJCAAEAONNzpS+JQAQAEzp6DY5tq8A8BsAmsyJZwgQIECAAAECBAgQIECAAAECBAgQIECAAIEeCwgABAA9Hu/5VxMACAB6PPACAAFAj8fb1QgQIECAAAECBAgQIECAAAECBAgQIECAAIEmAgIAAUCTOenNMwIAAUBvhnn+RQQAAoAej7erESBAgAABAgQIECBAgAABAgQIECBAgAABAk0EBAACgCZz0ptnBAACgN4MswBgZsXcX/jf/udKAUCPx9vVCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgSYCAgABQJM56c0zAgABQG+GWQAgAOjxMLsaAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMJ6AAEAAMN7kTOlbAgABwJSObpNj+woAvwGgyZx4hgABAgQIECBAgAABAgQIECBAgAABAgQIEOixgABAANDj8Z5/NQGAAKDHAy8AEAD0eLxdjQABAgQIECBAgAABAgQIECBAgAABAgQIEGgiIAAQADSZk948IwAQAPRmmOdfRAAgAOjxeLsaAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0ERAACAAaDInvXlGACAA6M0wCwBmVsz9hf/tf64UAPR4vF2NAAECBAgQIECAAAECBAgQIECAAAECBAgQaCIgABAANJmT3jwjABAA9GaYBQACgB4Ps6sRIECAAAECBAgQIECAAAECBAgQIECAAAEC4wkIAAQA403OlL4lABAATOnoNjm2rwDwGwCazIlnCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgR4LCAAEAD0e7/lXEwAIAHo88AIAAUCPx9vVCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgSYCAgABQJM56c0zAgABQG+Gef5FBAACgB6Pt6sRIECAAAECBAgQIECAAAECBAgQIECAAAECTQQEAAKAJnPSm2cEAAKA3gyzAGBmxdxf+N/+50oBQI/H29UIECBAgAABAgQIECBAgAABAgQIECBAgACBJgICAAFAkznpzTM1BQA7PTDZ/aHt0V51dnLN18df7/irk1W7jP/+nd98xx3/69LemlbarIDfACAA8BEhQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEBi4gABAADOojcODLkkP+or0rn/ny5Ftvb2+9xVzp2B8lK3du7wT/ctf21rJSIwEBgACg0aB4iAABAgQIECBAgAABAgQIECBAgAABAgQIEOivgABAANDf6XYzAsMSEAAIAIY18W5LgAABAgQIECBAgAABAgQIECBAgAABAgQIzBMQAAgAfCwIEOiHgABAANCPSXYLAgQIECBAgAABAgQIECBAgAABAgQIECBAYGwBAYAAYOzh8SIBAlUJCAAEAFUNpMMQIECAAAECBAgQIECAAAECBAgQIECAAAEC5QUEAAKA8lNnRwIEuhAQAAgAupgraxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJTJCAAEABM0bg6KgECmxEQAAgAfEAIECBAgAABAgQIECBAgAABAgQIECBAgACBgQsIAAQAA/8IuD6B3ggIAAQAvRlmFyFAgAABAgQIECBAgAABAgQIECBAgAABAgTGExAACADGmxxvESBQm4AAQABQ20w6DwECBAgQIECAAAECBAgQIECAAAECBAgQIFBYQAAgACg8crYjQKAjAQGAAKCj0bIsAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMC0CAgABwLTMqnMSILB5AQGAAMBnhAABAgQIECBAgAABAgQIECBAgAABAgQIEBi4gABAADDwj4DrE+iNgABAANCbYXYRAgQIECBAgAABAgQIECBAgAABAgQIECBAYDwBAYAAYLzJ8RYBArUJCAAEALXNpPMQIECAAAECBAgQIECAAAECBAgQIECAAAEChQUEAAKAwiNnOwIEOhIQAAgAOhotyxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQLTIiAAEABMy6w6JwECmxcQAAgAfEYIECBAgAABAgQIECBAgAABAgQIECBAgACBgQsIAAQAA/8IuD6B3ggIAAQAvRlmFyFAgAABAgQIECBAgAABAgQIECBAgAABAgTGExAACADGm5wpfWuPI5M9j57Sw0/Zsc969ZQdePqPKwAQAEz/FLsBAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMJGAAEAAMNEATdvLB70qOfyN03bq6TzvO+74X5fpPP8UnloAIACYwrF1ZAIECBAgQIAAAQIECBAgQIAAAQIECBAgQKBNAQGAAKDNeap+LQFAuR+RAKCc9dxOAgABQPGhsyEBAgQIECBAgAABAgQIECBAgAABAgQIECBQl4AAQABQ10R2fBoBQMfAGy0vAChnLQDIzNpkZqUAoPjQ2ZAAAQIECBAgQIAAAQIECBAgQIAAAQIECBCoS0AAIACoayI7Po0AoGNgAUA54Pk7+Q0AAoDFnD97EyBAgAABAgQIECBAgAABAgQIECBAgAABAhUICAAEABWMYbkjCADKWfsNAOWs53YSAAgAig+dDQkQIECAAAECBAgQIECAAAECBAgQIECAAIG6BAQAAoC6JrLj0wgAOgbeaHkBQDlrAYCvACg+bTYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEqhQQAAgAqhzMrg4lAOhKdv66AoBy1gIAAUDxabMhAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUKWAAEAAUOVgdnUoAUBXsgKAcrIL7uQrAHwFQAVj6AgECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAYgoIAAQAizl/xfcWAJQj9xsAylnP7SQAEAAUHzobEiBAgAABAgQIECBAgAABAgQIECBAgAABAnUJCAAEAHVNZMenEQB0DLzR8gKActYCAF8BUHzabEiAAAECBAgQIECAAAECBAgQIECAAAECBAhUKSAAEABUOZhdHUoA0JXs/HUFAOWsBQACgOLTZkMCBAgQIECAAAECBAgQIECAAAECBAgQIECgSgEBgACgysHs6lACgK5kBQDlZBfcyVcA+AqACsbQEQgQIECAAAECBAgQIECAAAECBAgQIECAAIHFFBAACAAWc/6K7y0AKEfuNwCUs57bSQAgACg+dDYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6hIQAAgA6prIjk8jAOgYeKPlBQDlrAUAvgKg+LTZkAABAgQIECBAgAABAgQIECBAgAABAgQIEKhSQAAgAKhyMLs6lACgK9n56woAylkLAAQAxafNhgQIECBAgAABAgQIECBAgAABAgQIECBAgECVAgIAAUCVg9nVoQQAXckKAMrJLriTrwDwFQAVjKEjECBAgAABAgQIECBAgAABAgQIECBAgAABAospIAAQACzm/BXfWwBQjtxvAChnPbeTAEAAUHzobEiAAAECBAgQIECAAAECBAgQIECAAAECBAjUJSAAEADUNZEdn0YA0DHwRssLAMpZCwB8BUDxabMhAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUKWAAEAAUOVgdnUoAUBXsvPXFQCUsxYACACKT5sNCRAgQIAAAQIECBAgQIAAAQIECBAgQIAAgSoFBAACgCoHs6tDCQC6khUAlJNdcCdfAeArACoYQ0cgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEFlNAACAAWMz5K763AKAcud8AUM56bicBgACg+NDZkAABAgQIECBAgAABAgQIECBAgAABAgQIEKhLQAAgAKhrIjs+jQCgY+CNlhcAlLMWAPgKgOLTZkMCBAgQIECAAAECBAgQIECAAAECBAgQIECgSgEBgACgysHs6lACgK5k568rAChnLQAQABSfNhsSIECAAAECBAgQIECAAAECBAgQIECAAAECVQoIAAQAVQ5mV4dqOwA4/U+S89/W1WnLrnv81cmqXdrbUwDQnmXDlXwFgK8AaDgqHiNAgAABAgQIECBAgAABAgQIECBAgAABAgT6KiAAEAD0dbY3eS8BwMI/bgHA1H8UBAACgKkfYhcgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEJhMQAAgAJpugKXtbACAAmLKRHeW4AgABwCjz4lkCBAgQIECAAAECBAgQIECAAAECBAgQIECghwICAAFAD8d64SsJAAQAPR54AYAAoMfj7WoECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAEwEBgACgyZz05hkBgACgN8M8/yICAAFAj8fb1QgQIECAAAECBAgQIECAAAECBAgQIECAAIEmAgIAAUCTOenNM20HAGe8LDnvLf3g+Z8/T1bu0N5d3nHH/7q0t6aVNisgABAA+IgQIECAAAECBAgQIECAAAECBAgQIECAAAECAxcQAAgABvURaDsA+PpfJ2e+YvoJlyxPXnRrsqTFv7QXABSfCwGAAKD40NmQAAECBAgQIECAAAECBAgQIECAAAECBAgQqEtAACAAqGsiOz5N2wHABf83+fzvdnzoAsuvulty/OXtbiQAaNezwWoCAAFAgzHxCAECBAgQIECAAAECBAgQIECAAAECBAgQINBnAQGAAKDP8z3vbm0HAJd+LPnPJ00/4U4PTJ71zXbvIQBo17PBagIAAUCDMfEIAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0GcBAYAAoM/z3XkAcOWZyYePmH7Cux+VPPlz7d5DANCuZ4PVBAACgAZj4hECBAgQIECAAAECBAgQIECAAAECBAgQIECgzwICAAFAn+e78wDg+h8m77339BPe55jkN05p9x4CgHY9G6wmABAANBgTjxAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQJ9FhAACAD6PN/z7vbglydHvLm9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AKA3wzzuRba7T3LMd5JlK8ZdoZv31q9Lbl6d3Hx1smzVhr/4X7FdN3tNsuolH00++eRJVvBuSwICAAFAS6NkGQIECBAgQIAAAQIECBAgQIAAAQIECBAgQGBaBQQAAoBpnd1Wz33E3yQP/tNWlxzEYutuS/5t/+S6iwZx3dovKQAQANQ+o85HgAABAgQIECBAgAABAgQIECBAgAABAgQIdCwgABAAdDxi07H8Vtslz7koWbXbdJy3llOe97+TM15ay2kGfw4BgABg8B8CAAQIECBAgAABAgQIECBAgAABAgQIECBAYOgCAgABwNA/A3fc//4vSo78RxxNBdZcnbxv3+TW65q+4bmOBQQAAoCOR8zyBAgQIECAAAECBAgQIECAAAECBAgQIECAQO0CAgABQO0zWu58S5Nnfj3Z+UHltpzmnb744uQ7gomafoQCAAFATfPoLAQIECBAgAABAgQIECBAgAABAgQIECBAgMAiCAgABACLMHb1brnroclTvpAsX1XvGWs42U+/mHz0qGRmXQ2ncYY5AQGAAMCHgQABAgQIECBAgAABAgQIECBAgAABAgQIEBi4gABAADDwj8D869/nWcljTkmW3PHpQLSxwHUXJx86IrnlGi6VCQgABACVjaTjECBAgAABAgQIECBAgAABAgQIECBAgAABAqUFBAACgNIzNxX7PeQ1yWFvmIqjFj3kzT9LPvzQ5LoLi25rs2YCAgABQLNJ8RQBAgQIECBAgAABAgQIECBAgAABAgQIECDQWwEBgACgt8M96cWOOjHZ73mTrtKf99fdmnzs6OTyL/TnTj27iQBAANCzkXYdAgQIECBAgAABAgQIECBAgAABAgQIECBAYFQBAYAAYNSZGczzS1ckT/pcssfDB3PlzV70tOOTC09kUbGAAEAAUPF4OhoBAgQIECBAgAABAgQIECBAgAABAgQIECBQQkAAIAAoMWdTu8fWuyRPPzPZ7t5Te4VWDn7uXyZnv7aVpSzSnYAAQADQ3XRZmQABAgQIECBAgAABAgQIECBAgAABAgQIEJgKAQGAAGAqBnUxD7nD/ZKnnp5svdNinmLx9r74lOSzz168/e3cWEAAIABoPCweJECAAAECBAgQIECAAAECBAgQIECAAAECBPopIAAQAPRzslu+1Xb3SR53arLT/i0vXPly5701+erLkpl1lR/U8WYF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QIAAAQIECBAgQIAAAQIEBi4gABAADOYjsM2vJcde0q/rvu++yXUXtnenZ56X7Pyg9tZbfV7ygQe3t56VNisgABAA+IgQIECAAAECBAgQIECAAAECBAgQIECAAAECAxcQAAgABvMRuO/vJI/6l35d95zXJ+f8eXt3avtrAG65NnnXju2dz0oCgK2SGV8B4JNAgAABAgQIECBAgAABAgQIECBAgAABAgQIENi0gABAADCYz8aj35vs++x+Xfe6i5P37dvendr+GoCZmeSdKzb8Y9n+1bmA3wDgNwB0PmQ2IECAAAECBAgQIECAAAECBAgQIECAAAECBOoWEAAIAOqe0BZPd9wVyV12b3HBSpb60BHJVWe2d5jjr05W7dLeev+6e3LzVe2tZ6UFBQQAAgAfDwIECBAgQIAAAQIECBAgQIAAAQIECBAgQGDgAgIAAcAgPgI7HpAcc34/r3r+3yen/1F7d3vG15JdDmpvvVMekFz73fbWs5IAwFcA+BQQIECAAAECBAgQIECAAAECBAgQIECAAAECBDYtIAAQAAzis7H/HySPeHv3V11zdXLthcn2+5T7bQNrrkpOvPuGL0Zv41+POzW515PbWGnDGh95ZHLFl9pbz0oLCvgNAH4DgI8HAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMHABAYAAYBAfgcPfnBz08m6uOvuX/me+Mrn8i8l1F/1yj232So74f5N9julm341X/djjkp98qp19Hv4PyQG/385as6t88mnJJR9pbz0rLSggABAA+HgQIECAAAECBAgQIECAAAECBAgQIECAAAECAxcQAAgABvEROPKfk/v/bvtXnf2n/T/x+OT67y+89v1ekPyPf2p/741XvPCk5LTj2tnjwa9IjvirdtaaXeXzL0wu+Of21rPSggICAAGAjwcBAgQIECBAgAABAgQIECBAgAABAgQIECAwcAEBgABgEB+Bx34k2fsp7V519XnJR49KbvnZltc99A3Jwa/Z8nPjPnHbjcm7d0/W3jTuCr9870EvTR72lsnXuX2Fr74i+cZft7eelRYUEAAIAHw8CBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgYELCAAEAIP4CDzly8kev97uVUf5tftLliW/dW6yy4HtnmHj1T53bHLRyZOv//C3Jwf8weTr3L7C2X+enPv69taz0oICAgABgI8HAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMHABAYAAYBAfgd++INnhvu1d9cqzkg8fPtp6d3tE8tQvjvbOKE9fdlry0UeP8samn338J5K9fnPydW5f4ct/lHzr79tbz0oLCggABAA+HgQIECBAgAABAgQIECBAgAABAgQIECBAgMDABQQAAoBBfASevzrZeuf2rvqJJyU/+tjo6z319ORuDxv9vSZvzMwk7713csMlTZ5e+Jm2Y4m2fjPBZLcaxNsCAAHAIAbdJQkQIECAAAECBAgQIECAAAECBAgQIECAAIGFBQQAAoBBfD5edFuydHk7V539i/Z/WpWsv2X09e7/wuTId47+XtM3vvE3yVf/rOnTm3huSfLCNcmylROscadXP/745Mf/2d56VlpQQAAgAPDxIECAAAECBAgQIECAAAECBAgQIECAAAECBAYuIAAQAAziI/D8a5Ktd2rnqjdelrznnuOttdV2yfFXJMtXjff+lt669frkpD2T267f0pOb/v/f49HJkz473rsLvfWhI5Krzmx3TattUkAAIADw0SBAgAABAgQIECBAgAABAgQIECBAgAABAgQGLiAAEAAM4iPw7IuT7e/TzlUv/1Jy6iPHX+vRJyf7Pmf897f05lmvTb72l1t6ahP//yXJM85NdjlojHc388r79kuuu6jdNa22SQEBgADAR4MAAQIECBAgQIAAAQIECBAgQIAAAQIECBAYuIAAQAAwiI/A089Kdju0nat+78Tkv44ff617/kbyxE+P//6W3ly7Jnn/AckNP9jSk7/6/9/v+OSofx3tnSZPv2uX5JZrmjzpmQkFBAACgAlHyOsECBAgQIAAAQIECBAgQIAAAQIECBAgQIDAtAsIAAQA0z7Djc7/hE8lex7d6NEtPvTdf06+8MItPrbwA0uT4y5L7nK3CdbYwqs//ULysaOT9bc222PlTskzz0u2GfOrDRbaZWYmeedWycy6Zufw1EQCAgABwEQD5GUCBAgQIECAAAECBAgQIECAAAECBAgQIEBg+gUEAAKA6Z/iBjd4zCnJPsc0eLDBI5d+IvnPJzR4cDOPPPKdyQMmiQgabH/x+5PPHbvhb0Q396/dH5rM+my7V4NFR3zkuouT9+074kseH1dAACAAGHd2vEeAAAECBAgQIECAAAECBAgQIECAAAECBAj0REAAIADoyShv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AoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zsIABpTeXD6BAQAAoDpm1onJkCAAAECBAgQIECAAAECBAgQIECAAAECBFoVEAAIAFodqNoXEwDU/hNyvgkEBAACgAnGx6sECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAHwQEAAKAPsxx4zu0HQD8/ILkxksbbz+oBz/+uEFdt4bLCgAEADXMoTMQIECAAAECBAgQIECAAAEC/z97dx72V13f+f+VOzskgYBJ2NdsIooKiCigAiJ1Q8EFEYTQ1tpOV3Xa308701prO3XGdqa1VVurlrZsbjAuyOIGxQUVF0RQw2pkkx0kJJDcc9E7xGC273LO+Z7l4XVx6XS+57M87vfhnzzzvQkQIECAAAECBEYoIAAQAIxw/KrfuugAoPobNGfH96//t0tzztzwkwoABAANH2HHJ0CAAAECBAgQIECAAAECBAgQIECAAAECBIYVEAAIAIadoUY9LwCo7sclAKjOet1OAgABQOVDZ0MCBAgQIECAAAECBAgQIECAAAECBAgQIECgXgICAAFAvSay5NMIAEoG3mB5AUB11gKAjD+ajE8XAFQ+dDYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6iUgABAA1GsiSz6NAKBkYAFAdcAb7+QbAAQAo5w/exMgQIAAAQIECBAgQIAAAQIECBAgQIAAAQI1EBAACABqMIbVHUEAUJ21bwCoznrdTgIAAUDlQ2dDAgQIECBAgAABAgQIECBAgAABAgQIECBAoF4CAgABQL0msuTTCABKBt5geQFAddYCAL8CoPJpsyEBAgQIECBAgAABAgQIECBAgAABAgQIECBQSwEBgACgloNZ1qEEAGXJbryuAKA6awGAAKDyabMhAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUEsBAYAAoJaDWdahBABlyQoAqpPd7E5+BYBfAVCDMXQEAgQIECBAgAABAgQIECBAgAABAgQIECBAYJQCAgABwCjnr/K9BQDVkfsGgOqs1+0kABAAVD50NiRAgAABAgQIECBAgAABAgQIECBAgAABAgTqJSAAEADUayJLPo0AoGTgDZYXAFRnLQDwKwAqnzYbEiBAgAABAgQIECBAgAABAgQIECBAgAABArUUEAAIAGo5mGUdSgBQluzG6woAqrMWAAgAKp82GxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQK1FBAACABqOZhlHUoAUJasAKA62c3u5FcA+BUANRhDRyBAgAABAgQIECBAgAABAgQIECBAgAABAgRGKSAAEACMcv4q31sAUB25bwCoznrdTgIAAUDlQ2dDAgQIECBAgAABAgQIECBAgAABAgQIECBAoF4CAgABQL0msuTTCABKBt5geQFAddYCAL8CoPJpsyEBAgQIECBAgAABAgQIECBAgAABAgQIECBQSwEBgACgloNZ1qEEAGXJbryuAKA6awGAAKDyabMhAQIECBAgQIAAAQIECBAgQIAAAQIECBAgUEsBAYAAoJaDWdahBABlyQoAqpPd7E5+BYBfAVCDMXQEAgQIECBAgAABAgQIECBAgAABAgQIECBAYJQCAgABwCjnr/K9BQDVkfsGgOqs1+0kABAAVD50NiRAgAABAgQIECBAgAABAgQIECBAgAABAgTqJSAAEADUayJLPo0AoGTgDZYXAFRnLQDwKwAqnzYbEiBAgAABAgQIECBAgAABAgQIECBAgAABArUUEAAIAGo5mGUdSgBQluzG6woAqrMWAAgAKp82GxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQK1FBAACABqOZhlHUoAUJasAKA62c3u5FcA+BUANRhDRyBAgAABAgQIECBAgAABAgQIECBAgAABAgRGKSAAEACMcv4q31sAUB25bwCoznrdTgIAAUDlQ2dDAgQIECBAgAABAgQIECBAgAABAgQIECBAoF4CAgABQL0msuTTCABKBt5geQFAddYCAL8CoPJpsyEBAgQIECBAgAABAgQIECBAgAABAgQIECBQSwEBgACgloNZ1qGKDgAeXJGsvL2s0zZ73Y8f1OzzN/D0vgHANwA0cGwdmQABAgQIECBAgAABAgQIECBAgAABAgQIEChSQAAgAChynmq/VtEBwOV/kFz1v2t/bQfshoAAQADQjUl3SwIECBAgQIAAAQIECBAgQIAAAQIECBAgQGCzAgIAAUCnXg8BQKd+3F27rABAANC1mXdfAgQIECBAgAABAgQIECBAgAABAgQIECBA4JcEBAACgE69FAKATv24u3ZZAYAAoGsz774ECBAgQIAAAQIECBAgQIAAAQIECBAgQICAACBjazbzh/4b/t/Hk7HH/pmUPBZJ/Of/fuyfx//35B7/b499fiwZW5tMfuy/H39+3X//TxNZrYAAoFpvu1UqIAAQAFQ6cDYjQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6ifgGwB8A0D9prLEEwkASsS19KgFBAACgFHPoP0JECBAgAABAgQIECBAgAABAgQIECBAgACBEQsIAAQAIx7BarcXAFTrbbdKBQQAAoBKB85mBAgQIECAAAECBAgQIECAAAECBAgQIECAQP0EBAACgPpNZYknEgCUiGvpUQsIAAQAo55B+xMgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIjFhAACABGPILVbi8AqNbbbpUKCAAEAJUOnM0IECBAgAABAgQIECBAgAABAgQIECBAgACB+gkIAAQA9ZvKEk8kACgR19KjFhAACABGPYP2J0CAAAECBAgQIECAAAECBAgQIECAAAECBEYsIAAQAIx4BKvdXgBQrbfdKhUQAAgAKh04mxEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQL1ExAACADqN5UlnkgAUCKupUctIAAQAIx6Bu1PgAABAgQIECBAgAABAgQIECBAgAABAgQIjFhAACAAGPEIVru9AKBab7tVKiAAEABUOnA2I0CAAAECBAgQIECAAAECBAgQIECAAAECBOonIAAQANRvKks8kQCgRFxLj1pAACAAGPUM2p8AAQIECBAgQIAAAQIECBAgQIAAAQIECBAYsYAAQAAw4hGsdnsBQDXek2ckax6uZi+7rBcQAAgAvA4ECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAxwUEAAKATr0CAoByf9zzDk6WLksWvi758Nxy97L6RgICAAGA14IAAQIECBAgQIAAAQIECBAgQIAAAQIECBDouIAAQADQqVdAAFD8j3vG/GTxyRN/8L/D/r9Y//3r/+1S/J5W3KSAAEAA4NUgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEOi4gABAAdOoVEAAU8+OeNCXZ41eSpacne7wkmTx143UFAMVY97GKAEAA0Me4+CgBAgQIECBAgAABAgQIECBAgAABAgQIECDQRgEBgACgjXO92TsJAIb7cc/dL1myLFl8SrLNgi2vJQAYznqApwUAAoABxsYjBAgQIECAAAECBAgQIECAAAECBAgQIECAQJsEBAACgDbN81bvIgDYKtFGH5i2XbLvayf+tv+CQ3p/XgDQu1VBnxQACAAKGiXLECBAgAABAgQIECBAgAABAgQIECBAgAABAk0VEAAIAJo6uwOde+qcZPr2Az26yYdW3ZM88kBx69VmpUnJLi9Ili5L9jkhmTKz/5MJAPo3G/IJAYAAYMgR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8FGcoH57fvrYZMWF9TuXE21WQAAgAPB6ECBAgAABAgQIECBAgAABAgQIECBAgAABAh0XEAAIADr9Cux02MTf9t/3NcnUWZ2m2OjyAoDGzYMAQADQuKF1YAIECBAgQIAAAQIECBAgQIAAAQIECBAgQKBYAQGAAKDYiWrAatvuOvH1/kuWJdsvasCBR3REAcCI4AffVgAgABh8ejxJgAABAgQIECBAgAABAgQIECBAgAABAgQItEJAACAAaMUg93qJpb+aHPGBZGxyr09093MCgMb97AUAAoDGDa0DEyBAgAABAgQIECBAgAABAgQIECBAgAABAsUKCAAEAMVOVM1Xe8bbkkPeVfND1uR4AoCa/CB6P4YAQADQ+7T4JAECBAgQIECAAAECBAgQIECAAAECBAgQINBKAQGAAKCVg725S7U9ALj/xmTtI8X8agMBQONeDQGAAKBxQ+vABAgQIECAAAECBAgQIECAAAECBAgQIECAQLECAgABQLETVfPV2hgArLwjWX5usvzM5PavJUe8P9nvjcP/IAQAwxtWvIIAQABQ8cjZjgABAgQIECBAgAABAgQIECBAgAABAgQIEKibgABAAFC3mSz1PG0JAFbfn9zwyeTHZyU/vSQZX/MLtiM+IAAodYjqu7gAQABQ3+l0MgIECBAgQIAAAQIECBAgQIAAAQIECBAgQKASAQGAAKCSQavLJk0OANasSm767MTf9L/p08mahzetKgCoy7RVfg4BgACg8qGzIQECBAgQIECAAAECBAgQIECAAAECBAgQIFAvAQGAAKBeE1nyaZoWAKxdk9zyxeTHZyY3fCJZfd/WgQQAWzdq6ScEAAKAlo62axEgQIAAAQIECBAgQIAAAQIECBAgQIAAAQK9CggABAC9zkorPteUAOD2r0/8of915yYrb+uPXgDQn1eLPi0AEAC0aJxdhQABAgQIECBAgAABAgQIECBAgAABAgQIEBhEQAAgABhkbhr7TJ0DgLt/kCw/a+Kf+68bnFgAMLhdw58UAAgAGj7Cjk+AAAECBAgQIECAAAECBAgQIECAAAECBAgMKyAAEAAMO0ONer5uAcADNyfLz06Wn5nc9d1iKAUAxTg2cBUBgACggWPryAQIECBAgAABAgQIECBAgAABAgQIECBAgECRAgIAAUCR81T7teoQAKy8M7n+oxNf8X/b5UnGi2UTABTr2aDVBAACgAaNq6MSIECAAAECBAgQIECAAAECBAgQIECAAAECZQgIAAQAZcxVbdccVQDwyIPJDedNfL3/Ty6a+FPKsv4jAChLtvbrCgAEALUfUgckQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEyhUQAAgAyp2wmq1eZQCwZnXyk89N/E3/mz6VPPpQNRgCgGqca7iLAEAAUMOxdCQCBAgQIECAAAECBAgQIECAAAECBAgQIECgSgEBgACgynkb+V5VBgD3XJtc88HkunOSn6+o7uoCgOqsa7aTAEAAULORdBwCBAgQIECAAAECBAgQIECAAAECBAgQIECgagEBgACg6pkb6X5VBgCPX3R8PLn10olvArj+Y8mqu8slEACU61vj1QUAAoAaj6ejESBAgAABAgQIECBAgAABAgQIECBAgAABAlUICAAEAFXMWW32GEUAsOHl1zySrLhwIga48fxyfi2AAKA241b1QQQAAoCqZ85+BAgQIECAAAECBAgQIECAAAECBAgQIECAQM0EBAACgJqNZLnHGXUAsOHtHvn5RATw47MmooC1jxRzdwFAMY4NXEUAIABo4Ng6MgECBAgQIECAAAECBAgQIECAAAECBAgQIFCkgABAAFDkPNV+rToFABtiPXxXct3HkuVnJrdelmR8cEoBwOB2DX9SACAAaPgIOz4BAgQIECBAgAABAgQIECBAgAABAgQIECAwrIAAQAAw7Aw16vm6BgAbIj64Ill+9sSvCbjr2/3zCgD6N2vJEwIAAUBLRtk1CBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgUEFBAACgEFnp5HPNSEA2BD2nmuT5WdNxAD3L++NXADQm1MLPyUAEAC0cKxdiQABAgQIECBAgAABAgQIECBAgAABAgQIEOhHQAAgAOhnXhr/2aYFABuC3/GNiRDgunOSh27d/I9CAND4MR30AgIAAcCgs+M5AgQIECBAgAABAgQIECBAgAABAgQIECBAoCUCAgABQEtGubdrNDkAePyG42uTW740EQNc//Fk9b1PvLsAoLdZaOGnBAACgBaOtSsRIECAAAECBAgQIECAAAECBAgQIECAAAEC/QgIAAQA/cxL4z/bhgBgwx/CmtXJzRcky89MbvxUsmZlIgBo/JgOegEBgABg0NnxHAECBAgQIECAAAECBAgQIECAAAECBAgQ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vuTiVycrLm7bzVp5HwGAAKCVg+1SBAgQIECAAAECBAgQIECAAAECBAgQIECAQO8CAgABQO/T0sFP7nR4cuwnkxk7dvDy66689tHk8t9Lrv6H7ho05OYCAAFAQ0bVMQkQIECAAAECBAgQIECAAAECBAgQIECAAIGyBAQAAoCyZqvx6y48KXnBh5PJ0xp/lUIucNV7J0KArC1kOYsULyAAEAAUP1VWJECAAAECBAgQIECAAAECBAgQIECAAAECBBolIAAQADRqYKs67M5HJC/7fDI2paodm7HPt9+dfP2PmnHWDp5SACAA6ODYuzIBAgQIECBAgAABAgQIECBAgAABAgQIECCwoYAAQADgjfglgW13TU74VrLNAjSbErjkpGT5WWxqKCAAEADUcCwdiQABAgQIECBAgAABAgQIECBAgAABAgQIEKhSQAAgAKhy3mq/19j05LgvJwsOqf1RR3bAR1cmn3xucte3R3YEG29aQAAgAPBuECBAgAABAgQIECBAgAABAgQIECBAgAABAh0XEAAIADr+Cjzx+s/7p+TJv4ZkawIP3Jx8/KDk4Z9t7ZP+/ysUEAAIACocN1sRIECAAAECBAgQIECAAAECBAgQIECAAAECdRQQAAgA6jiXIznTk9+YPO8DI9m6kZve8uXkU0dP/Imr/9RCQAAgAKjFIDoEAQIECBAgQIAAAQIECBAgQIAAAQIECBAgMDoBAYAAYHTTV6Od5z974qv/J0+r0aEacJTv/33yH7/dgIN244gCAAFANybdLQkQIECAAAECBAgQIECAAAECBAgQIECAAIHNCggABACdfz1mzE9e/e1k2106TzEQwJd+Lbn2nwd61EPFCggABADFTpTVCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgcYJCAAEAI0b2qIPfPj7kqe8qehVu7Pe6geSM/dNHv5Zd+5c05sKAAQANR1NxyJAgAABAgQIECBAgAABAgQIECBAgAABAgSqEhAACACqmrVa7jN7n+TEa5PJU2t5vMYc6nv/O/nKHzTmuG09qABAANDW2XYvAgQIECBAgAABAgQIECBAgAABAgQIECBAoEcBAYAAoMdRaefHjjwjWXxKO+9W5a3WrErOXJT8/CdV7mqvXxIQAAgAvBQECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAxwUEAAKAzr4Cc/dLXnNVMmls9ATja5Pbv5b85KLkwZuSh25PHrotWXl78vCdydTZyTYLkpnr/tlmp2TBocnuxyTTtx/9+R87wbUfSr70q/U4S0dPIQAQAHR09F2bAAECBAgQIECAAAECBAgQIECAAAECBAgQeFxAACAA6OzbcMzHk32OH931Vz+Q3PyZ5KbPJDdfkKy6q/+zTJqS7PScZI+XJHsfl2y/pP81inpi7Zrk3P2Te68takXr9CkgABAA9DkyPk6AAAECBAgQIECAAAECBAgQIECAAAECBAi0TUAAIABo20z3dJ8nHZi86ps9fbTwDz3yUPL99ybf+atk1d0FLj8p2eeE5OA/S+Y+ucB1+1jquo8lF7+6jwd8tEgBAYAAoMh5shYBAgQIECBAgAABAgQIECBAgAABAgQIECDQQAEBgACggWM7/JFf8rlk9xcNv04/K6xZnfzgA8mVf5GsvK2fJ/v77KTJyaKTk4P+JJmzd3/PFvHpjx2U3PmtIlayRp8CAgABQJ8j4+MECBAgQIAAAQIECBAgQIAAAQIECBAgQIBA2wQEAAKAts30Vu+z0+HJKy7d6scK/cC9P0o+94rk3msKXXaLi41NS577t8lTfqO6PR/b6ScXJ585pto97fafAgIAAYBXgQABAgQIECBAgAABAgQIECBAgAABAgQIEOi4gABAANC5V+CF5yb7Vvg19Td9Ovn8ycnq+0ZD/eRfTw57bzJ5WnX7n/OU5J4fVLefnQQAjybj0wUAXgUCBAgQIECAAAECBAgQIECAAAECBAgQIECg4wICAAFAp16BqbOTU+9Ipswo/9rj48mVf55840+TrC1/vy3tsODQ5JiPJ9vuXM05Hvs1B1e8vZq97LJewDcACAC8DgQIECBAgAABAgQIECBAgAABAgQIECBAgEDHBQQAAoBOvQKLT02O/Eg1V77ivydXvrOavXrZZbtFyfFfT6bP7eXTw33m/huTM/dJMj7cOp7uS0AAIADoa2B8mAABAgQIECBAgAABAgQIECBAgAABAgQIEGifgABAANC+qd7CjV5yUbL7C8u/8vJzkktOLH+ffnfY5cjkpRcmY1P6fbL/z593eHLbf/T/nCcGFhAACAAGHh4PEiBAgAABAgQIECBAgAABAgQIECBAgAABAu0QEAAIANoxyT3cYtrc5LSfJWOTe/jwEB+54xvJ+c9L1qwcYpESH93vN5Ij3l/iBuuWvupvk8t/r/x97LBeQAAgAPA6ECBAgAABAgQIECBAgAABAgQIECBAgAABAh0XEAAIADrzCuz58uRXzi/3ug/fnZz71OShW8rdZ9jVD39f8pQ3DbvKlp+/66rko08rdw+rP0FAACAA8EoQIECAAAECBAgQIECAAAECBAgQIECAAAECHRcQAAgAOvMKHPqe5IA3l3vdr7w1+d57yt2jiNWnbZ+ctDyZsWMRq216jfHx5CPzklV3lbeHlZ8gIAAQAHglCBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgY4LCAAEAJ15BU74ZjLvwPKu+8DNyVmLk7WrytujyJWf+vvJc/+myBU3XuvCE5IbPlHuHlZfLyAAEAB4HQgQIECAAAECBAgQIECAAAECBAgQIECAAIGOCwgABACdeAWmzkmW3Z2MTS7vul84NfnRGeWtX/TKY9OSE69J5uxT9Mq/WO+qv00u/73y1rfyEwQEAAIArwQBAgQIECBAgAABAgQIECBAgAABAgQIECDQcQEBgACgE6/A/Gcnx3+1vKvefXVy7mO/735teXuUsfLC1yVHn1nGyhNr/vSLyaeOLG99Kz9BQAAgAPBKECBAgAABAgQIECBAgAABAgQIECBAgAABAh0XEAAIADrxCiw6JTmqxL+d//W3Jd/+y+ZRPvYtAKf9LJk2p5yzP7gi+bfdy1nbqhsJCAAEAF4LAgQIECBAgAABAgQIECBAgAABAgQIECBAoOMCAgABQCdegYP/LDnwv5V31XP2T+65urz1y1z56LOTha8tZ4fx8eSfZyWPPlTO+lZ9goAAQADglSBAgAABAgQIECBAgAABAgQIECBAgAABAgQ6LiAAEAB04hU4+qxk4YnlXPW+65KzFpazdhWr7nti8sKzytvp3AOSu79X3vpWXi8gABAAeB0IECBAgAABAgQIECBAgAABAgQIECBAgACBjgsIAAQAnXgFXvnVZMGzy7nqd/86+epbylm7ilWnbZecekcyeVo5u13w8uSmT5WztlWfICAAEAB4JQgQIECAAAECBAgQIECAAAECBAgQIECAAIGOCwgABACdeAVec3Wyw37lXPUzL05+ckE5a1e16nGXJTsfVs5unz85+fG/l7O2VQUAjybj09b9wf90AYBXggABAgQIECBAgAABAgQIECBAgAABAgQIEOi4gABA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gABAAFCviSz5NGUFAOPjyRVvT779lyVfYIjl9/+d5Dl/nYxNGWKRPh4VAPSBVcxHBQACgGImySoECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAYwUEAAKAxg7vIAcvIwB45OfJF05JbvjkICeq9pldj06OOTeZPrf8fQUA5Rv/0g4CAAFA5UNnQwIECBAgQIAAAQIECBAgQIAAAQIECBAgQKBeAgIAAUC9JrLk0xQdADy4Irng5cld3y754AUuv92i5Njzk7lPLnDRTSwlACjXdxOrCwAEAJUPnQ0JECBAgAABAgQIECBAgAABAgQIECBAgACBegkIAAQA9ZrIkk9TZABw+xXJha9IHrq15EOXsPy07ZKjzkz2fHEJi69bUgBQnu1mVhYACAAqHzobEiBAgAABAgQIECBAgAABAgQIECBAgAABAvUSEAAIAOo1kSWfpqgAYPnZyRdPT9asLPnAZS4/lhz67uSAt5SziQCgHNctrCoAEABUPnQ2JECAAAECBAgQIECAAAECBAgQIECAAAECBOolIAAQANRrIks+zbABwPh48s13JN/6syTjJR+2ouUXn5o87wPJ5OnFbigAKNazh9UEAAKAHsbERwgQIECAAAECBAgQIECAAAECBAgQIECAAIE2CwgABABtnu+N7jZMAPDoyuSLpyXXnds+sgWHJi/6RLLNTsXdTQBQnGWPKwkABAA9joqPESBAgAABAgQIECBAgAABAgQIECBAgAABAm0VEAAIANo625u816ABwM9vTT53XPKzb7SXa9vdkmPPS+YdWMwdBQDFOPaxigBAANDHuPgoAQIECBAgQIAAAQIECBAgQIAAAQIECBAg0EYBAYAAoI1zvdk7DRIA/OzKiT/8//mK9lNNnpm84MPJwtcOf1cBwPCGfa4gABAA9DkyPk6AAAECBAgQIECAAAECBAgQIECAAAECBAi0TUAAIABo20xv8T79BgDXfyL5winJow91iinP/OPk4D9LJq3/N0T/9xcA9G825BMCAAHAkCPkcQIECBAgQIAAAQIECBAgQIAAAQIECBAgQKDpAgIAAUDTZ7iv8/cTAFz5F8kVf5xkvK8tWvPhvV+ZHHlGMnXWYFcSAAzmNsRTAgABwBDj41ECBAgQIECAAAECBAgQIECAAAECBAgQIECgDQICAAFAG+a45zv0EgCsWZV86deSH/9bz8u29oM7PC059vxkzl79X1EA0L/ZkE8IAAQAQ46QxwkQIECAAAECBAgQIECAAAECBAgQIECAAIGmCwgABABNn+G+zr+1AGDlHcnnXpnc/pW+lm31h2fMS475WLLLEf1dUwDQn1cBnxYACAAKGCNLECBAgAABAgQIECBAgAABAgQIECBAgAABAk0WEAAIAJo8v32ffUsBwF3fSy54efLgTX0v2/oHxqYmh7032e+NvV9VANC7VUGfFAAIAAoaJcsQIECAAAECBAgQIECAAAECBAgQIECAAAECTRUQAAgAmjq7A517cwHAjZ9KLjkpefTBgZbtzEP7/07ynL9OxqZs/coCgK0bFfwJAYAAoOCRshwBAgQIECBAgAABAgQIECBAgAABAgQIECDQNAEBgACgaTM71Hk3FQB89z3JV/8wydqhlu7Mw7senbzwnGTGDlu+sgCg8pEQAAgAKh86GxIgQIAAAQIECBAgQIAAAQIECBAgQIAAAQL1EhAACADqNZEln2bDAGDN6uTS30x++KGSN23h8tstSo49P5n75M1fTgBQ+Q9eACAAqHzobEiAAAECBAgQIECAAAECBAgQIECAAAECBAjUS0AAIACo10SWfJrHA4CVdyYXnZDcemnJG7Z4+WnbJUedmez54k1fUgBQ+Q9fACAAqHzobEiAAAECBAgQIECAAAECBAgQIECAAAECBAjUS0AAIACo10SWfJrHAoBFr08ueFnywPUlb9aF5ceSZ/9V8vS3bnxZAUDlAyAAEABUPnQ2JECAAAECBAgQIECAAAECBAgQIECAAAECBOolIAAQANRrIks+zc7PS+76TrL6vpI36tjyi9+QPO8fk8nTf3FxAUDlQyAAEABUPnQ2JECAAAECBAgQIECAAAECBAgQIECAAAECBOolIAAQANRrIp2msQLzn50c+8lkm50mriAAqPxHKQAQAFQ+dDYkQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE6iUgABAA1GsinabRAtvulhx7XjLvQAHACH6QAgABwAjGzpYECBAgQIAAAQIECBAgQIAAAQIECBAgQIBAnQQEAAKAOs2js7RAYPLM5AUfSi55XQsu06wrCAAEAM2aWKclQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEChcQAAgACh8qCxIgMBIBAYAAYCSDZ1MCBAgQIECAAAECBAgQIECAAAECBAgQIECgPgICAAFAfabRSQgQGEZAACAAGGZ+PEuAAAECBAgQIECAAAECBAgQIECAAAECBAi0QEAAIABowRi7AgECSQQAAgAvAgECBAgQIECAAAECBAgQIECAAAECBAgQINBxAQGAAKDjr4DrE2iNgABAANCaYXYRAgQIECBAgAABAgQIECBAgAABAgQIECBAYDABAYAAYLDJ8VSnBebun2y7c7Li4k4z1O3yAgABQN1m0nkIECBAgAABAgQIECBAgAABAgQIECBAgACBigUEAAKAikfOdk0WmL1XctA7ksUnJw/fmZy1JFl9b5Nv1KqzCwAEAK0aaJchQIAAAQIECBAgQIAAAQIECBAgQIAAAQIE+hcQAAgA+p8aT3ROYMb85MC3J/u9KZk87RfXv+rvkst/t3Mcdb2wAEAAUNfZdC4CBAgQIECAAAECBAgQIECAAAECBAgQIECgIgEBgACgolGzTRMFps5JDnhLcsCbk6mzNr7B2jXJxw9M7vpuE2/XujMLAAQArRtqFyJAgAABAgQIECBAgAABAgQIECBAgAABAgT6ExAACAD6mxiffoLAY38zfufDk213TmbOTx77f2+zYN3/npesWZmsvGPjf277SnLvNfXFHJue7P9byTPelsx80pbPeet/JOcfXt+7dOhkAgABQIfG3VUJECBAgAABAgQIECBAgAABAgQIECBAgACBTQkIAAQA3ox+BMaS+Qcle7x44p95ByWT1r9F/SyU3PvD5IZPTvxzxzeSjPf3fBmfnjQ5WfyG5KA/TWbv0fsOn39D8uN/7f3zPlmKgABAAFDKYFmUAAECBAgQIECAAAECBAgQIECAAAECBAgQaI6AAEAA0JxpHeFJZ+0x8bfh9zk+mTmv+IM8uCL55juSa/95dCHA3q9MnvWuZO6T+7/fQ7clZy1JHrm//2c9UZiAAEAAUNgwWYgAAQIECBAgQIAAAQIECBAgQIAAAQIECBBopoAAQADQzMmt6NSPfaX/M9+WPOVNyeTp5W96+9eSS38zues75e/1+A67vCA55C+TBYcMt+d3/yb56puHW8PTQwkIAAQAQw2QhwkQIECAAAECBAgQIECAAAECBAgQIECAAIHmCwgABADNn+ISbjBtu+SAtyZP+/1k6qwSNtjCkmvXJFf/ffLV/5qsXV3e3k96ZnLIXyS7v6iYPR59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APcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBB4AgEJAE/wI7oEAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAgAcA9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEnkBAAsAT/IgugQABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQISABwDxAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgScQkADwBD+iSyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAhIA3AMECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQOAJBCQAPMGP6BIIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgIAEAPcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBB4AgEJAE/wI7oEAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAgAcA9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEnkBAAsAT/IgugQABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQISABwDxAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgScQkADwBD+iSyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAhIA3AMECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQOAJBCQAPMGP6BIIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgIAEAPcAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBB4AgEJAE/wI7oEAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECAgAcA9QIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIEnkBAAsAT/IgugQABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQISABwDxAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAgScQkADwBD+iSyBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgAABAhIA3AMECBAgQIAAAQIECBAgQIAAAQIECBAgQIAAAQIECBAgQOAJBCQAPMGP6BIIECBAgAABAgQIECBAgAABAgQIECBAgAABAgQIECBAgMD/AbM2QTg/scFAAAAAAElFTkSuQmCC" - ] - } -} \ No newline at end of file diff --git a/015-flare-splashscreen/flare_splash/lib/main.dart b/015-flare-splashscreen/flare_splash/lib/main.dart deleted file mode 100644 index 34f18ba4..00000000 --- a/015-flare-splashscreen/flare_splash/lib/main.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flare_splash_screen/flare_splash_screen.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flare Welcome', - home: SplashScreen( - 'assets/splash.flr', - (context) => HomeView(), - startAnimation: 'intro', - backgroundColor: Color(0xff181818), - ), - ); - } -} - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Color(0xff181818), - body: Center( - child: Text( - 'Home View', - style: TextStyle(color: Colors.white), - ), - ), - ); - } -} diff --git a/015-flare-splashscreen/flare_splash/pubspec.lock b/015-flare-splashscreen/flare_splash/pubspec.lock deleted file mode 100644 index 740aca87..00000000 --- a/015-flare-splashscreen/flare_splash/pubspec.lock +++ /dev/null @@ -1,175 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flare_dart: - dependency: transitive - description: - name: flare_dart - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.4" - flare_flutter: - dependency: transitive - description: - name: flare_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.3" - flare_loading: - dependency: transitive - description: - name: flare_loading - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - flare_splash_screen: - dependency: "direct main" - description: - name: flare_splash_screen - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.7.8 <2.0.0" diff --git a/015-flare-splashscreen/flare_splash/pubspec.yaml b/015-flare-splashscreen/flare_splash/pubspec.yaml deleted file mode 100644 index 0fa74226..00000000 --- a/015-flare-splashscreen/flare_splash/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: flare_splash -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - flare_splash_screen: ^3.0.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - splash.flr - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/015-flare-splashscreen/flare_splash/test/widget_test.dart b/015-flare-splashscreen/flare_splash/test/widget_test.dart deleted file mode 100644 index 4c16ad87..00000000 --- a/015-flare-splashscreen/flare_splash/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flare_splash/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/.gitignore b/018-bottom-sheet-guide/bottom_sheet_guide/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/.metadata b/018-bottom-sheet-guide/bottom_sheet_guide/.metadata deleted file mode 100644 index 4d089672..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/.metadata +++ /dev/null @@ -1,10 +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: b712a172f9694745f50505c93340883493b505e5 - channel: stable - -project_type: app diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/README.md b/018-bottom-sheet-guide/bottom_sheet_guide/README.md deleted file mode 100644 index 19e1a9b3..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# bottom_sheet_guide - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/lib/bottomsheet_widget.dart b/018-bottom-sheet-guide/bottom_sheet_guide/lib/bottomsheet_widget.dart deleted file mode 100644 index 78dfd481..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/lib/bottomsheet_widget.dart +++ /dev/null @@ -1,106 +0,0 @@ -import 'package:flutter/material.dart'; - -class BottomSheetWidget extends StatefulWidget { - const BottomSheetWidget({Key key}) : super(key: key); - - @override - _BottomSheetWidgetState createState() => _BottomSheetWidgetState(); -} - -class _BottomSheetWidgetState extends State { - @override - Widget build(BuildContext context) { - return Container( - margin: const EdgeInsets.only(top: 5, left: 15, right: 15), - height: 160, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Container( - height: 125, - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(15), - boxShadow: [ - BoxShadow( - blurRadius: 10, color: Colors.grey[300], spreadRadius: 5) - ]), - child: Column( - children: [ - DecoratedTextField(), - SheetButton() - ], - ), - ) - ], - ), - ); - } -} - -class DecoratedTextField extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container( - height: 50, - alignment: Alignment.center, - padding: const EdgeInsets.all(10), - margin: const EdgeInsets.all(10), - decoration: BoxDecoration( - color: Colors.grey[300], - borderRadius: BorderRadius.circular(10), - ), - child: TextField( - decoration: - InputDecoration.collapsed(hintText: 'Enter your reference number'), - ), - ); - } -} - -class SheetButton extends StatefulWidget { - SheetButton({Key key}) : super(key: key); - - _SheetButtonState createState() => _SheetButtonState(); -} - -class _SheetButtonState extends State { - bool checkingFlight = false; - bool success = false; - - @override - Widget build(BuildContext context) { - return !checkingFlight - ? MaterialButton( - color: Colors.grey[800], - onPressed: () async { - setState(() { - checkingFlight = true; - }); - - await Future.delayed(Duration(seconds:1)); - - setState(() { - success = true; - }); - - await Future.delayed(Duration(milliseconds: 500)); - - Navigator.pop(context); - }, - child: Text( - 'Check Flight', - style: TextStyle( - color: Colors.white, - ), - ), - ) - : !success - ? CircularProgressIndicator() - : Icon( - Icons.check, - color: Colors.green, - ); - } -} diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/lib/main.dart b/018-bottom-sheet-guide/bottom_sheet_guide/lib/main.dart deleted file mode 100644 index 12afd35e..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/lib/main.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:bottom_sheet_guide/bottomsheet_widget.dart'; -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp(title: 'Flutter Demo', home: HomeView()); - } -} - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Scaffold( - floatingActionButton: MyFloatingButton(), - ); - } -} - -class MyFloatingButton extends StatefulWidget { - @override - _MyFloatingButtonState createState() => _MyFloatingButtonState(); -} - -class _MyFloatingButtonState extends State { - bool _show = true; - @override - Widget build(BuildContext context) { - return _show - ? FloatingActionButton( - onPressed: () { - var sheetController = showBottomSheet( - context: context, - builder: (context) => BottomSheetWidget()); - - _showButton(false); - - sheetController.closed.then((value) { - _showButton(true); - }); - }, - ) - : Container(); - } - - void _showButton(bool value) { - setState(() { - _show = value; - }); - } -} - diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/pubspec.lock b/018-bottom-sheet-guide/bottom_sheet_guide/pubspec.lock deleted file mode 100644 index 066a096b..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/pubspec.lock +++ /dev/null @@ -1,146 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/pubspec.yaml b/018-bottom-sheet-guide/bottom_sheet_guide/pubspec.yaml deleted file mode 100644 index 12997fdd..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/pubspec.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: bottom_sheet_guide -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/018-bottom-sheet-guide/bottom_sheet_guide/test/widget_test.dart b/018-bottom-sheet-guide/bottom_sheet_guide/test/widget_test.dart deleted file mode 100644 index c8044f42..00000000 --- a/018-bottom-sheet-guide/bottom_sheet_guide/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:bottom_sheet_guide/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/019-animation-basics/.gitignore b/019-animation-basics/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/019-animation-basics/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/019-animation-basics/.metadata b/019-animation-basics/.metadata deleted file mode 100644 index 4d089672..00000000 --- a/019-animation-basics/.metadata +++ /dev/null @@ -1,10 +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: b712a172f9694745f50505c93340883493b505e5 - channel: stable - -project_type: app diff --git a/019-animation-basics/README.md b/019-animation-basics/README.md deleted file mode 100644 index 2a709b12..00000000 --- a/019-animation-basics/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# animation_guide - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/019-animation-basics/lib/animation_widget.dart b/019-animation-basics/lib/animation_widget.dart deleted file mode 100644 index cb7bb881..00000000 --- a/019-animation-basics/lib/animation_widget.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -class AnimatedWidgetView extends StatefulWidget { - AnimatedWidgetView({Key key}) : super(key: key); - - _AnimatedWidgetViewState createState() => _AnimatedWidgetViewState(); -} - -class _AnimatedWidgetViewState extends State - with TickerProviderStateMixin { - AnimationController controller; - - @override - void initState() { - super.initState(); - controller = - AnimationController(vsync: this, duration: const Duration(seconds: 3)); - controller.forward(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center(child: GrowingContainer(controller: controller,)), - ); - } -} - -class GrowingContainer extends AnimatedWidget { - GrowingContainer({AnimationController controller}) - : super( - listenable: Tween(begin: 0, end: 200).animate(controller)); - - @override - Widget build(BuildContext context) { - Animation animation = listenable; - return Container( - height: animation.value, - width: animation.value, - color: Colors.red, - ); - } -} diff --git a/019-animation-basics/lib/basic_animation.dart b/019-animation-basics/lib/basic_animation.dart deleted file mode 100644 index 51c0d984..00000000 --- a/019-animation-basics/lib/basic_animation.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -class BasicAnimationView extends StatefulWidget { - BasicAnimationView({Key key}) : super(key: key); - - _BasicAnimationViewState createState() => _BasicAnimationViewState(); -} - -class _BasicAnimationViewState extends State - with TickerProviderStateMixin { - AnimationController controller; - Animation growAnimation; - - @override - void initState() { - super.initState(); - controller = - AnimationController(vsync: this, duration: const Duration(seconds: 3)) - ..addListener(() { - setState(() {}); - }); - growAnimation = Tween(begin: 0, end: 200).animate(controller); - controller.forward(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Container( - height: growAnimation.value, - width: growAnimation.value, - color: Colors.red, - ), - ), - ); - } -} diff --git a/019-animation-basics/lib/hooks_view.dart b/019-animation-basics/lib/hooks_view.dart deleted file mode 100644 index 1331bf25..00000000 --- a/019-animation-basics/lib/hooks_view.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; - -class HooksView extends HookWidget { - @override - Widget build(BuildContext context){ - var controller = useAnimationController(duration: Duration(seconds: 3)); - controller.forward(); - return Scaffold( - body: Center(child: GrowingContainer(controller: controller,)), - ); - } -} - -class GrowingContainer extends AnimatedWidget { - GrowingContainer({AnimationController controller}) - : super( - listenable: Tween(begin: 0, end: 200).animate(controller)); - - @override - Widget build(BuildContext context) { - Animation animation = listenable; - return Container( - height: animation.value, - width: animation.value, - color: Colors.red, - ); - } -} diff --git a/019-animation-basics/lib/main.dart b/019-animation-basics/lib/main.dart deleted file mode 100644 index 20fb28ae..00000000 --- a/019-animation-basics/lib/main.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'sequence_animation.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp(title: 'Flutter Demo', home: SequenceAnimationView()); - } -} diff --git a/019-animation-basics/lib/sequence_animation.dart b/019-animation-basics/lib/sequence_animation.dart deleted file mode 100644 index d7c00471..00000000 --- a/019-animation-basics/lib/sequence_animation.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_sequence_animation/flutter_sequence_animation.dart'; - -class SequenceAnimationView extends StatefulWidget { - SequenceAnimationView({Key key}) : super(key: key); - - _SequenceAnimationViewState createState() => _SequenceAnimationViewState(); -} - -class _SequenceAnimationViewState extends State - with TickerProviderStateMixin { - AnimationController controller; - SequenceAnimation sequenceAnimation; - - @override - void initState() { - super.initState(); - controller = AnimationController(vsync: this); - sequenceAnimation = SequenceAnimationBuilder() - .addAnimatable( - animatable: Tween(begin: 0, end: 200), - from: const Duration(milliseconds: 0), - to: const Duration(milliseconds: 300), - tag: 'grow') - .addAnimatable( - animatable: Tween(begin: 0, end: 1), - from: const Duration(milliseconds: 0), - to: const Duration(milliseconds: 400), - tag: 'fade-in') - .addAnimatable( - animatable: Tween(begin: 100, end: 0), - from: const Duration(milliseconds: 300), - to: const Duration(milliseconds: 800), - tag: 'margin-slide') - .animate(controller); - - controller.forward(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: AnimatedBuilder( - animation: controller, - builder: (context, child) => Opacity( - opacity: sequenceAnimation['fade-in'].value, - child: Container( - margin: EdgeInsets.only( - left: sequenceAnimation['margin-slide'].value), - height: sequenceAnimation['grow'].value, - width: MediaQuery.of(context).size.width, - color: Colors.purple, - ), - ), - ), - ), - ); - } -} diff --git a/019-animation-basics/pubspec.lock b/019-animation-basics/pubspec.lock deleted file mode 100644 index fe4af913..00000000 --- a/019-animation-basics/pubspec.lock +++ /dev/null @@ -1,160 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_hooks: - dependency: "direct main" - description: - name: flutter_hooks - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.0" - flutter_sequence_animation: - dependency: "direct main" - description: - name: flutter_sequence_animation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/019-animation-basics/pubspec.yaml b/019-animation-basics/pubspec.yaml deleted file mode 100644 index 8b5bc5f4..00000000 --- a/019-animation-basics/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: animation_guide -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - flutter_hooks: ^0.9.0 - flutter_sequence_animation: - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/019-animation-basics/test/widget_test.dart b/019-animation-basics/test/widget_test.dart deleted file mode 100644 index 961c1ba0..00000000 --- a/019-animation-basics/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:animation_guide/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/021-completer_dialogs/01-start/.gitignore b/021-completer_dialogs/01-start/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/021-completer_dialogs/01-start/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/021-completer_dialogs/01-start/.metadata b/021-completer_dialogs/01-start/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/021-completer_dialogs/01-start/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/021-completer_dialogs/01-start/README.md b/021-completer_dialogs/01-start/README.md deleted file mode 100644 index f41c7c3e..00000000 --- a/021-completer_dialogs/01-start/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# dialog_manager - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/021-completer_dialogs/01-start/lib/locator.dart b/021-completer_dialogs/01-start/lib/locator.dart deleted file mode 100644 index 247b3bbb..00000000 --- a/021-completer_dialogs/01-start/lib/locator.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() {} diff --git a/021-completer_dialogs/01-start/lib/main.dart b/021-completer_dialogs/01-start/lib/main.dart deleted file mode 100644 index 86567483..00000000 --- a/021-completer_dialogs/01-start/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:dialog_manager/locator.dart'; -import 'package:dialog_manager/ui/home/home_view.dart'; -import 'package:flutter/material.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - home: HomeView(), - ); - } -} diff --git a/021-completer_dialogs/01-start/lib/ui/home/home_view.dart b/021-completer_dialogs/01-start/lib/ui/home/home_view.dart deleted file mode 100644 index d31ebed1..00000000 --- a/021-completer_dialogs/01-start/lib/ui/home/home_view.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:dialog_manager/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider.value( - value: HomeViewModel(), - child: Consumer( - builder: (context, model, child) => Scaffold( - body: Center( - child: FlatButton( - child: Text('Show Dialog'), - onPressed: () { - model.doThings(); - }, - ), - ), - ), - ), - ); - } -} diff --git a/021-completer_dialogs/01-start/lib/viewmodels/home_view_model.dart b/021-completer_dialogs/01-start/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 37ae4aa9..00000000 --- a/021-completer_dialogs/01-start/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class HomeViewModel extends ChangeNotifier { - Future doThings() async {} -} diff --git a/021-completer_dialogs/01-start/pubspec.lock b/021-completer_dialogs/01-start/pubspec.lock deleted file mode 100644 index ee75ebff..00000000 --- a/021-completer_dialogs/01-start/pubspec.lock +++ /dev/null @@ -1,182 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - event_bus: - dependency: "direct main" - description: - name: event_bus - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - rflutter_alert: - dependency: "direct main" - description: - name: rflutter_alert - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/021-completer_dialogs/01-start/pubspec.yaml b/021-completer_dialogs/01-start/pubspec.yaml deleted file mode 100644 index 724a80f4..00000000 --- a/021-completer_dialogs/01-start/pubspec.yaml +++ /dev/null @@ -1,70 +0,0 @@ -name: dialog_manager -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - rflutter_alert: ^1.0.3 - event_bus: ^1.1.1 - get_it: ^4.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/021-completer_dialogs/01-start/test/widget_test.dart b/021-completer_dialogs/01-start/test/widget_test.dart deleted file mode 100644 index e4941372..00000000 --- a/021-completer_dialogs/01-start/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:dialog_manager/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/021-completer_dialogs/02-manager-setup/.gitignore b/021-completer_dialogs/02-manager-setup/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/021-completer_dialogs/02-manager-setup/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/021-completer_dialogs/02-manager-setup/.metadata b/021-completer_dialogs/02-manager-setup/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/021-completer_dialogs/02-manager-setup/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/021-completer_dialogs/02-manager-setup/README.md b/021-completer_dialogs/02-manager-setup/README.md deleted file mode 100644 index f41c7c3e..00000000 --- a/021-completer_dialogs/02-manager-setup/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# dialog_manager - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/021-completer_dialogs/02-manager-setup/lib/locator.dart b/021-completer_dialogs/02-manager-setup/lib/locator.dart deleted file mode 100644 index a222b76b..00000000 --- a/021-completer_dialogs/02-manager-setup/lib/locator.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:dialog_manager/services/dialog_service.dart'; -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => DialogService()); -} diff --git a/021-completer_dialogs/02-manager-setup/lib/main.dart b/021-completer_dialogs/02-manager-setup/lib/main.dart deleted file mode 100644 index e65e02cd..00000000 --- a/021-completer_dialogs/02-manager-setup/lib/main.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:dialog_manager/locator.dart'; -import 'package:dialog_manager/ui/home/home_view.dart'; -import 'package:flutter/material.dart'; - -import 'managers/dialog_manager.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: (context, widget) => Navigator( - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager( - child: widget, - ), - ), - ), - title: 'Dialog Manager Setup', - home: HomeView(), - ); - } -} \ No newline at end of file diff --git a/021-completer_dialogs/02-manager-setup/lib/managers/dialog_manager.dart b/021-completer_dialogs/02-manager-setup/lib/managers/dialog_manager.dart deleted file mode 100644 index 01546674..00000000 --- a/021-completer_dialogs/02-manager-setup/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:dialog_manager/locator.dart'; -import 'package:dialog_manager/services/dialog_service.dart'; -import 'package:flutter/material.dart'; -import 'package:rflutter_alert/rflutter_alert.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog() { - Alert( - context: context, - title: "FilledStacks", - desc: "Flutter is awesome.", - closeFunction: () => _dialogService.dialogComplete(), - buttons: [ - DialogButton( - child: Text('OkieDoke'), - onPressed: () { - _dialogService.dialogComplete(); - Navigator.of(context).pop(); - }, - ) - ]).show(); - } -} diff --git a/021-completer_dialogs/02-manager-setup/lib/services/dialog_service.dart b/021-completer_dialogs/02-manager-setup/lib/services/dialog_service.dart deleted file mode 100644 index 06b1f9ca..00000000 --- a/021-completer_dialogs/02-manager-setup/lib/services/dialog_service.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'dart:async'; - -class DialogService { - Function _showDialogListener; - Completer _dialogCompleter; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog() { - _dialogCompleter = Completer(); - _showDialogListener(); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete() { - _dialogCompleter.complete(); - _dialogCompleter = null; - } -} \ No newline at end of file diff --git a/021-completer_dialogs/02-manager-setup/lib/ui/home/home_view.dart b/021-completer_dialogs/02-manager-setup/lib/ui/home/home_view.dart deleted file mode 100644 index d31ebed1..00000000 --- a/021-completer_dialogs/02-manager-setup/lib/ui/home/home_view.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:dialog_manager/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider.value( - value: HomeViewModel(), - child: Consumer( - builder: (context, model, child) => Scaffold( - body: Center( - child: FlatButton( - child: Text('Show Dialog'), - onPressed: () { - model.doThings(); - }, - ), - ), - ), - ), - ); - } -} diff --git a/021-completer_dialogs/02-manager-setup/lib/viewmodels/home_view_model.dart b/021-completer_dialogs/02-manager-setup/lib/viewmodels/home_view_model.dart deleted file mode 100644 index f911668c..00000000 --- a/021-completer_dialogs/02-manager-setup/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:dialog_manager/locator.dart'; -import 'package:dialog_manager/services/dialog_service.dart'; -import 'package:flutter/foundation.dart'; - -class HomeViewModel extends ChangeNotifier { - DialogService _dialogService = locator(); - - Future doThings() async { - print('dialog called'); - var dialogResult = await _dialogService.showDialog(); - print('dialog closed'); - } -} diff --git a/021-completer_dialogs/02-manager-setup/pubspec.lock b/021-completer_dialogs/02-manager-setup/pubspec.lock deleted file mode 100644 index 0007e2e5..00000000 --- a/021-completer_dialogs/02-manager-setup/pubspec.lock +++ /dev/null @@ -1,175 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - rflutter_alert: - dependency: "direct main" - description: - name: rflutter_alert - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/021-completer_dialogs/02-manager-setup/pubspec.yaml b/021-completer_dialogs/02-manager-setup/pubspec.yaml deleted file mode 100644 index f5a2f7f6..00000000 --- a/021-completer_dialogs/02-manager-setup/pubspec.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: dialog_manager -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - rflutter_alert: ^1.0.3 - get_it: ^4.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/021-completer_dialogs/02-manager-setup/test/widget_test.dart b/021-completer_dialogs/02-manager-setup/test/widget_test.dart deleted file mode 100644 index e4941372..00000000 --- a/021-completer_dialogs/02-manager-setup/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:dialog_manager/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/021-completer_dialogs/03-final/.gitignore b/021-completer_dialogs/03-final/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/021-completer_dialogs/03-final/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/021-completer_dialogs/03-final/.metadata b/021-completer_dialogs/03-final/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/021-completer_dialogs/03-final/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/021-completer_dialogs/03-final/README.md b/021-completer_dialogs/03-final/README.md deleted file mode 100644 index f41c7c3e..00000000 --- a/021-completer_dialogs/03-final/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# dialog_manager - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/021-completer_dialogs/03-final/lib/datamodels/alert_request.dart b/021-completer_dialogs/03-final/lib/datamodels/alert_request.dart deleted file mode 100644 index 5cf75050..00000000 --- a/021-completer_dialogs/03-final/lib/datamodels/alert_request.dart +++ /dev/null @@ -1,11 +0,0 @@ -class AlertRequest { - final String title; - final String description; - final String buttonTitle; - - AlertRequest({ - this.title, - this.description, - this.buttonTitle, - }); -} diff --git a/021-completer_dialogs/03-final/lib/datamodels/alert_response.dart b/021-completer_dialogs/03-final/lib/datamodels/alert_response.dart deleted file mode 100644 index d6c5551a..00000000 --- a/021-completer_dialogs/03-final/lib/datamodels/alert_response.dart +++ /dev/null @@ -1,11 +0,0 @@ -class AlertResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - AlertResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/021-completer_dialogs/03-final/lib/locator.dart b/021-completer_dialogs/03-final/lib/locator.dart deleted file mode 100644 index a222b76b..00000000 --- a/021-completer_dialogs/03-final/lib/locator.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:dialog_manager/services/dialog_service.dart'; -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => DialogService()); -} diff --git a/021-completer_dialogs/03-final/lib/main.dart b/021-completer_dialogs/03-final/lib/main.dart deleted file mode 100644 index f167718a..00000000 --- a/021-completer_dialogs/03-final/lib/main.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:dialog_manager/locator.dart'; -import 'package:dialog_manager/managers/dialog_manager.dart'; -import 'package:dialog_manager/ui/home/home_view.dart'; -import 'package:flutter/material.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - builder: (context, widget) => Navigator( - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager( - child: widget, - )), - ), - home: HomeView(), - ); - } -} diff --git a/021-completer_dialogs/03-final/lib/managers/dialog_manager.dart b/021-completer_dialogs/03-final/lib/managers/dialog_manager.dart deleted file mode 100644 index 9a8b84f4..00000000 --- a/021-completer_dialogs/03-final/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,46 +0,0 @@ -import 'package:dialog_manager/datamodels/alert_request.dart'; -import 'package:dialog_manager/datamodels/alert_response.dart'; -import 'package:dialog_manager/locator.dart'; -import 'package:dialog_manager/services/dialog_service.dart'; -import 'package:flutter/material.dart'; -import 'package:rflutter_alert/rflutter_alert.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(AlertRequest request) { - Alert( - context: context, - title: request.title, - desc: request.description, - closeFunction: () => - _dialogService.dialogComplete(AlertResponse(confirmed: false)), - buttons: [ - DialogButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService.dialogComplete(AlertResponse(confirmed: true)); - Navigator.of(context).pop(); - }, - ) - ]).show(); - } -} diff --git a/021-completer_dialogs/03-final/lib/services/dialog_service.dart b/021-completer_dialogs/03-final/lib/services/dialog_service.dart deleted file mode 100644 index c9938423..00000000 --- a/021-completer_dialogs/03-final/lib/services/dialog_service.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'dart:async'; - -import 'package:dialog_manager/datamodels/alert_request.dart'; -import 'package:dialog_manager/datamodels/alert_response.dart'; - -class DialogService { - Function(AlertRequest) _showDialogListener; - Completer _dialogCompleter; - - void registerDialogListener(Function(AlertRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - Future showDialog( - {String title, String description, String buttonTitle = 'OK'}) { - _dialogCompleter = Completer(); - _showDialogListener(AlertRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - void dialogComplete(AlertResponse response) { - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/021-completer_dialogs/03-final/lib/ui/home/home_view.dart b/021-completer_dialogs/03-final/lib/ui/home/home_view.dart deleted file mode 100644 index d31ebed1..00000000 --- a/021-completer_dialogs/03-final/lib/ui/home/home_view.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:dialog_manager/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider.value( - value: HomeViewModel(), - child: Consumer( - builder: (context, model, child) => Scaffold( - body: Center( - child: FlatButton( - child: Text('Show Dialog'), - onPressed: () { - model.doThings(); - }, - ), - ), - ), - ), - ); - } -} diff --git a/021-completer_dialogs/03-final/lib/viewmodels/home_view_model.dart b/021-completer_dialogs/03-final/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 22e56b9b..00000000 --- a/021-completer_dialogs/03-final/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:dialog_manager/locator.dart'; -import 'package:dialog_manager/services/dialog_service.dart'; -import 'package:flutter/foundation.dart'; - -class HomeViewModel extends ChangeNotifier { - final DialogService _dialogService = locator(); - Future doThings() async { - print('dialog shown'); - var dialogResult = await _dialogService.showDialog( - title: 'Dialog Manager', - description: 'FilledStacks architecture is always awesome'); - - if (dialogResult.confirmed) { - print('User has confirmed'); - } else { - print('User cancelled the dialog'); - } - } -} diff --git a/021-completer_dialogs/03-final/pubspec.lock b/021-completer_dialogs/03-final/pubspec.lock deleted file mode 100644 index 0007e2e5..00000000 --- a/021-completer_dialogs/03-final/pubspec.lock +++ /dev/null @@ -1,175 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - rflutter_alert: - dependency: "direct main" - description: - name: rflutter_alert - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/021-completer_dialogs/03-final/pubspec.yaml b/021-completer_dialogs/03-final/pubspec.yaml deleted file mode 100644 index f5a2f7f6..00000000 --- a/021-completer_dialogs/03-final/pubspec.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: dialog_manager -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - rflutter_alert: ^1.0.3 - get_it: ^4.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/021-completer_dialogs/03-final/test/widget_test.dart b/021-completer_dialogs/03-final/test/widget_test.dart deleted file mode 100644 index e4941372..00000000 --- a/021-completer_dialogs/03-final/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:dialog_manager/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/022-lifecycle-manager/.gitignore b/022-lifecycle-manager/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/022-lifecycle-manager/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/022-lifecycle-manager/.metadata b/022-lifecycle-manager/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/022-lifecycle-manager/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/022-lifecycle-manager/README.md b/022-lifecycle-manager/README.md deleted file mode 100644 index 5ed112ac..00000000 --- a/022-lifecycle-manager/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# lifecycle_manager - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/022-lifecycle-manager/lib/lifecycle_manager.dart b/022-lifecycle-manager/lib/lifecycle_manager.dart deleted file mode 100644 index 92ceccd3..00000000 --- a/022-lifecycle-manager/lib/lifecycle_manager.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lifecycle_manager/locator.dart'; -import 'package:lifecycle_manager/services/background_fetch_service.dart'; -import 'package:lifecycle_manager/services/location_service.dart'; -import 'package:lifecycle_manager/services/stoppable_service.dart'; - -/// Stop and start long running services -class LifeCycleManager extends StatefulWidget { - final Widget child; - LifeCycleManager({Key key, this.child}) : super(key: key); - - _LifeCycleManagerState createState() => _LifeCycleManagerState(); -} - -class _LifeCycleManagerState extends State - with WidgetsBindingObserver { - List servicesToManage = [ - locator(), - locator(), - ]; - - // Get all services - - @override - Widget build(BuildContext context) { - return widget.child; - } - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addObserver(this); - } - - @override - void dispose() { - super.dispose(); - WidgetsBinding.instance.removeObserver(this); - } - - @override - void didChangeAppLifecycleState(AppLifecycleState state) { - super.didChangeAppLifecycleState(state); - servicesToManage.forEach((service) { - if (state == AppLifecycleState.resumed) { - service.start(); - } else { - service.stop(); - } - }); - } -} diff --git a/022-lifecycle-manager/lib/locator.dart b/022-lifecycle-manager/lib/locator.dart deleted file mode 100644 index a21a9849..00000000 --- a/022-lifecycle-manager/lib/locator.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:lifecycle_manager/services/background_fetch_service.dart'; -import 'package:lifecycle_manager/services/location_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => LocationService()); - locator.registerLazySingleton(() => BackgroundFetchService()); -} diff --git a/022-lifecycle-manager/lib/main.dart b/022-lifecycle-manager/lib/main.dart deleted file mode 100644 index fc202ef6..00000000 --- a/022-lifecycle-manager/lib/main.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:lifecycle_manager/locator.dart'; - -import 'lifecycle_manager.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return LifeCycleManager( - child: MaterialApp( - title: 'Flutter Demo', - home: Scaffold( - body: Center( - child: FlutterLogo(), - ), - ), - ), - ); - } -} diff --git a/022-lifecycle-manager/lib/services/background_fetch_service.dart b/022-lifecycle-manager/lib/services/background_fetch_service.dart deleted file mode 100644 index c0694d31..00000000 --- a/022-lifecycle-manager/lib/services/background_fetch_service.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:lifecycle_manager/services/stoppable_service.dart'; - -class BackgroundFetchService extends StoppableService { - @override - void start() { - super.start(); - - // Start listeneing - print('BackgroundFetchService Started $serviceStopped'); - } - - @override - void stop() { - super.stop(); - - // stop listening - print('BackgroundFetchService Stopped $serviceStopped'); - } -} \ No newline at end of file diff --git a/022-lifecycle-manager/lib/services/location_service.dart b/022-lifecycle-manager/lib/services/location_service.dart deleted file mode 100644 index e89f7043..00000000 --- a/022-lifecycle-manager/lib/services/location_service.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:lifecycle_manager/services/stoppable_service.dart'; - -class LocationService extends StoppableService { - @override - void start() { - super.start(); - print('LocationService Started $serviceStopped'); - } - - @override - void stop() { - super.stop(); - print('LocationService Stopped $serviceStopped'); - } -} \ No newline at end of file diff --git a/022-lifecycle-manager/lib/services/stoppable_service.dart b/022-lifecycle-manager/lib/services/stoppable_service.dart deleted file mode 100644 index e4e21c13..00000000 --- a/022-lifecycle-manager/lib/services/stoppable_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -abstract class StoppableService { - bool _serviceStoped = false; - bool get serviceStopped => _serviceStoped; - - @mustCallSuper - void stop() { - _serviceStoped = true; - } - - @mustCallSuper - void start() { - _serviceStoped = false; - } -} \ No newline at end of file diff --git a/022-lifecycle-manager/pubspec.lock b/022-lifecycle-manager/pubspec.lock deleted file mode 100644 index 90a30dd3..00000000 --- a/022-lifecycle-manager/pubspec.lock +++ /dev/null @@ -1,153 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/022-lifecycle-manager/pubspec.yaml b/022-lifecycle-manager/pubspec.yaml deleted file mode 100644 index 847898df..00000000 --- a/022-lifecycle-manager/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: lifecycle_manager -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - get_it: ^4.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/022-lifecycle-manager/test/widget_test.dart b/022-lifecycle-manager/test/widget_test.dart deleted file mode 100644 index 4d8554e8..00000000 --- a/022-lifecycle-manager/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:lifecycle_manager/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/023-abstraction-setup-fakedata/.gitignore b/023-abstraction-setup-fakedata/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/023-abstraction-setup-fakedata/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/023-abstraction-setup-fakedata/.metadata b/023-abstraction-setup-fakedata/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/023-abstraction-setup-fakedata/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/023-abstraction-setup-fakedata/README.md b/023-abstraction-setup-fakedata/README.md deleted file mode 100644 index 4c20883e..00000000 --- a/023-abstraction-setup-fakedata/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# abstraction_example - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/023-abstraction-setup-fakedata/lib/datamodels/api_models.dart b/023-abstraction-setup-fakedata/lib/datamodels/api_models.dart deleted file mode 100644 index 4e9e25a6..00000000 --- a/023-abstraction-setup-fakedata/lib/datamodels/api_models.dart +++ /dev/null @@ -1,18 +0,0 @@ -class Post {} - -class Comment {} - -class User { - final String name; - final String phoneNumber; - - User({this.name, this.phoneNumber}); -} - -class LoginResponse { - final bool success; - final int userId; - final String message; - - LoginResponse({this.success, this.userId, this.message}); -} diff --git a/023-abstraction-setup-fakedata/lib/locator.dart b/023-abstraction-setup-fakedata/lib/locator.dart deleted file mode 100644 index 9327fe15..00000000 --- a/023-abstraction-setup-fakedata/lib/locator.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:abstraction_example/services/api/api.dart'; -import 'package:abstraction_example/services/api/fake_api.dart'; -import 'package:abstraction_example/services/api/http_api.dart'; -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -const bool USE_FAKE_IMPLEMENTATION = true; - -void setupLocator() { - locator.registerLazySingleton( - () => USE_FAKE_IMPLEMENTATION ? FakeApi() : HttpApi()); -} diff --git a/023-abstraction-setup-fakedata/lib/main.dart b/023-abstraction-setup-fakedata/lib/main.dart deleted file mode 100644 index f49895b8..00000000 --- a/023-abstraction-setup-fakedata/lib/main.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'locator.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/023-abstraction-setup-fakedata/lib/providers_setup.dart b/023-abstraction-setup-fakedata/lib/providers_setup.dart deleted file mode 100644 index bbcc5b14..00000000 --- a/023-abstraction-setup-fakedata/lib/providers_setup.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:abstraction_example/services/api/api.dart'; -import 'package:abstraction_example/services/api/fake_api.dart'; -import 'package:abstraction_example/services/api/http_api.dart'; -import 'package:provider/provider.dart'; -import 'package:provider/single_child_widget.dart'; - -const bool USE_FAKE_IMPLEMENTATION = true; - -List provders = [ - ...independentServices, - ...dependentServices, - ...uiConsumableProviders -]; -List independentServices = [ - Provider.value(value: USE_FAKE_IMPLEMENTATION ? FakeApi() : HttpApi()) -]; -List dependentServices = []; -List uiConsumableProviders = []; diff --git a/023-abstraction-setup-fakedata/lib/services/api/api.dart b/023-abstraction-setup-fakedata/lib/services/api/api.dart deleted file mode 100644 index e5085b29..00000000 --- a/023-abstraction-setup-fakedata/lib/services/api/api.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:abstraction_example/datamodels/api_models.dart'; - -abstract class Api { - Future login({String username, String password}); - - Future getUser(int userId); - - Future> getPostsForUser(int userId); - - Future> getCommentsForPost(int postId); -} \ No newline at end of file diff --git a/023-abstraction-setup-fakedata/lib/services/api/fake_api.dart b/023-abstraction-setup-fakedata/lib/services/api/fake_api.dart deleted file mode 100644 index 6a531d45..00000000 --- a/023-abstraction-setup-fakedata/lib/services/api/fake_api.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:abstraction_example/datamodels/api_models.dart'; - -import 'api.dart'; - -class FakeApi implements Api { - @override - Future> getCommentsForPost(int postId) async { - await Future.delayed(Duration(seconds: 1)); - - if (postId == 1) { - return List.generate(10, (index) => Comment()); - } - - return null; - } - - @override - Future> getPostsForUser(int userId) async { - await Future.delayed(Duration(seconds: 1)); - - if (userId == 1) { - return List.generate(10, (index) => Post()); - } - - if (userId == 2) { - return List(); - } - - return null; - } - - @override - Future getUser(int userId) async { - await Future.delayed(Duration(seconds: 1)); - - if (userId == 1) { - return User(name: 'dane', phoneNumber: '999-999-00'); - } - - if (userId == 2) { - return User(phoneNumber: '999-999-00'); - } - - return null; - } - - @override - Future login({String username, String password}) async { - await Future.delayed(Duration(seconds: 1)); - - if (username == 'dane') { - return LoginResponse(userId: 1); - } - - if(username == 'filledstacks') { - return LoginResponse(success: false, message: 'User does not exist'); - } - - if(username == 'halfman') { - return LoginResponse(userId: 2); - } - - return null; - } -} diff --git a/023-abstraction-setup-fakedata/lib/services/api/http_api.dart b/023-abstraction-setup-fakedata/lib/services/api/http_api.dart deleted file mode 100644 index d7d03a7c..00000000 --- a/023-abstraction-setup-fakedata/lib/services/api/http_api.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:abstraction_example/datamodels/api_models.dart'; - -import 'api.dart'; - -class HttpApi implements Api { - @override - Future> getCommentsForPost(int postId) { - // TODO: implement getCommentsForPost - return null; - } - - @override - Future> getPostsForUser(int userId) { - // TODO: implement getPostsForUser - return null; - } - - @override - Future getUser(int userId) { - // TODO: implement getUser - return null; - } - - @override - Future login({String username, String password}) { - // TODO: implement login - return null; - } -} diff --git a/023-abstraction-setup-fakedata/pubspec.lock b/023-abstraction-setup-fakedata/pubspec.lock deleted file mode 100644 index 3e1ebe13..00000000 --- a/023-abstraction-setup-fakedata/pubspec.lock +++ /dev/null @@ -1,168 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/023-abstraction-setup-fakedata/pubspec.yaml b/023-abstraction-setup-fakedata/pubspec.yaml deleted file mode 100644 index 4d6f0251..00000000 --- a/023-abstraction-setup-fakedata/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: abstraction_example -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - get_it: ^4.0.2 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/023-abstraction-setup-fakedata/test/widget_test.dart b/023-abstraction-setup-fakedata/test/widget_test.dart deleted file mode 100644 index 1ab218c2..00000000 --- a/023-abstraction-setup-fakedata/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:abstraction_example/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/024-abstraction-unit-test/01-start-getit/.flutter-plugins-dependencies b/024-abstraction-unit-test/01-start-getit/.flutter-plugins-dependencies deleted file mode 100644 index 98a8e13e..00000000 --- a/024-abstraction-unit-test/01-start-getit/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+1/","dependencies":[]}],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]}],"date_created":"2020-06-18 21:49:36.328970","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/024-abstraction-unit-test/01-start-getit/.gitignore b/024-abstraction-unit-test/01-start-getit/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/024-abstraction-unit-test/01-start-getit/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/024-abstraction-unit-test/01-start-getit/.metadata b/024-abstraction-unit-test/01-start-getit/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/024-abstraction-unit-test/01-start-getit/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/024-abstraction-unit-test/01-start-getit/README.md b/024-abstraction-unit-test/01-start-getit/README.md deleted file mode 100644 index e3a8ac68..00000000 --- a/024-abstraction-unit-test/01-start-getit/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# abstraction_unit - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/024-abstraction-unit-test/01-start-getit/lib/datamodels/post.dart b/024-abstraction-unit-test/01-start-getit/lib/datamodels/post.dart deleted file mode 100644 index 4d2a97b8..00000000 --- a/024-abstraction-unit-test/01-start-getit/lib/datamodels/post.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Post { - String title; - int likeCount; - - Post({this.title, this.likeCount}); - - Post.fromMap(Map map) { - title = map['title']; - likeCount = map['likeCount']; - } - - Map toMap() { - var map = {'title': title, 'likeCount': likeCount}; - return map; - } -} diff --git a/024-abstraction-unit-test/01-start-getit/lib/locator.dart b/024-abstraction-unit-test/01-start-getit/lib/locator.dart deleted file mode 100644 index 3b88ea35..00000000 --- a/024-abstraction-unit-test/01-start-getit/lib/locator.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:abstraction_unit/services/api.dart'; -import 'package:abstraction_unit/services/localstorage_service.dart'; -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => Api()); - locator.registerLazySingleton(() => LocalStorageService()); -} \ No newline at end of file diff --git a/024-abstraction-unit-test/01-start-getit/lib/main.dart b/024-abstraction-unit-test/01-start-getit/lib/main.dart deleted file mode 100644 index cc192a57..00000000 --- a/024-abstraction-unit-test/01-start-getit/lib/main.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/024-abstraction-unit-test/01-start-getit/lib/services/api.dart b/024-abstraction-unit-test/01-start-getit/lib/services/api.dart deleted file mode 100644 index 02058634..00000000 --- a/024-abstraction-unit-test/01-start-getit/lib/services/api.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:http/http.dart' as http; - -class Api { - static const endpoint = 'https://myapi.com'; - - var client = new http.Client(); - - Future likePost(int postId) async { - var response = - await client.post('$endpoint/likePost/$postId'); - - if(response.statusCode == 200) { - return true; - } - - return false; - } -} diff --git a/024-abstraction-unit-test/01-start-getit/lib/services/localstorage_service.dart b/024-abstraction-unit-test/01-start-getit/lib/services/localstorage_service.dart deleted file mode 100644 index 43cf7c88..00000000 --- a/024-abstraction-unit-test/01-start-getit/lib/services/localstorage_service.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:async'; - -import 'package:abstraction_unit/datamodels/post.dart'; -import 'package:localstorage/localstorage.dart'; - -class LocalStorageService { - final LocalStorage _postsStorage = new LocalStorage('postsStorage'); - final StreamController _postUpdated = StreamController.broadcast(); - - Stream get postUpdateStream => _postUpdated.stream; - - Future likePost(int postId, {bool unlike = false}) async { - // Get all the current posts - Map data = _postsStorage.getItem('user_posts'); - - // check if the one we're liking is in the collection - if (data.containsKey('$postId')) { - // convert to a post - var post = Post.fromMap(data['$postId']); - - if (!unlike) { - // increment like count - post.likeCount++; - } else { - // decrement like count - post.likeCount--; - } - // change back to map and save to the data - data['$postId'] = post.toMap(); - // save all the data back to the local storage - await _postsStorage.setItem('user_posts', data); - // indicate the post Id has updated so the widget can reload itself - _postUpdated.add(postId); - return true; - } else { - print('Data for post $postId is not on disk. Add from api after fetch.'); - return false; - } - } - - void dispose() { - _postUpdated.close(); - } -} diff --git a/024-abstraction-unit-test/01-start-getit/lib/services/post_service.dart b/024-abstraction-unit-test/01-start-getit/lib/services/post_service.dart deleted file mode 100644 index b0dcd10a..00000000 --- a/024-abstraction-unit-test/01-start-getit/lib/services/post_service.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:abstraction_unit/locator.dart'; -import 'package:abstraction_unit/services/localstorage_service.dart'; -import 'api.dart'; - -class PostService { - Api _api = locator(); - LocalStorageService _localStorageService = locator(); - - Future likePost(int postId) async { - var localLikeSuccess = await _localStorageService.likePost(postId); - var postLiked = await _api.likePost(postId); - - if (postLiked) { - return true; - } - - // TODO: Revert the local like - if (localLikeSuccess) { - await _localStorageService.likePost(postId, unlike: true); - } - - return false; - } -} diff --git a/024-abstraction-unit-test/01-start-getit/pubspec.lock b/024-abstraction-unit-test/01-start-getit/pubspec.lock deleted file mode 100644 index 5809e216..00000000 --- a/024-abstraction-unit-test/01-start-getit/pubspec.lock +++ /dev/null @@ -1,252 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - localstorage: - dependency: "direct main" - description: - name: localstorage - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2+5" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+1" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+3" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.13" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.0" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/024-abstraction-unit-test/01-start-getit/pubspec.yaml b/024-abstraction-unit-test/01-start-getit/pubspec.yaml deleted file mode 100644 index 4029ef04..00000000 --- a/024-abstraction-unit-test/01-start-getit/pubspec.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: abstraction_unit -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - http: - get_it: - localstorage: ^3.0.2+5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/024-abstraction-unit-test/01-start-getit/test/postservice_test.dart b/024-abstraction-unit-test/01-start-getit/test/postservice_test.dart deleted file mode 100644 index d5fdd8b0..00000000 --- a/024-abstraction-unit-test/01-start-getit/test/postservice_test.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:abstraction_unit/services/post_service.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group('PostService Test | ', () { - test('Constructing Service should find correct dependencies', () { - var postService = PostService(); - expect(postService != null, true); - }); - }); -} diff --git a/024-abstraction-unit-test/01-start-provider/.flutter-plugins-dependencies b/024-abstraction-unit-test/01-start-provider/.flutter-plugins-dependencies deleted file mode 100644 index 12966b0e..00000000 --- a/024-abstraction-unit-test/01-start-provider/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+1/","dependencies":[]}],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]}],"date_created":"2020-06-18 21:49:37.844370","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/024-abstraction-unit-test/01-start-provider/.gitignore b/024-abstraction-unit-test/01-start-provider/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/024-abstraction-unit-test/01-start-provider/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/024-abstraction-unit-test/01-start-provider/.metadata b/024-abstraction-unit-test/01-start-provider/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/024-abstraction-unit-test/01-start-provider/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/024-abstraction-unit-test/01-start-provider/README.md b/024-abstraction-unit-test/01-start-provider/README.md deleted file mode 100644 index e3a8ac68..00000000 --- a/024-abstraction-unit-test/01-start-provider/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# abstraction_unit - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/024-abstraction-unit-test/01-start-provider/lib/datamodels/post.dart b/024-abstraction-unit-test/01-start-provider/lib/datamodels/post.dart deleted file mode 100644 index 4d2a97b8..00000000 --- a/024-abstraction-unit-test/01-start-provider/lib/datamodels/post.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Post { - String title; - int likeCount; - - Post({this.title, this.likeCount}); - - Post.fromMap(Map map) { - title = map['title']; - likeCount = map['likeCount']; - } - - Map toMap() { - var map = {'title': title, 'likeCount': likeCount}; - return map; - } -} diff --git a/024-abstraction-unit-test/01-start-provider/lib/main.dart b/024-abstraction-unit-test/01-start-provider/lib/main.dart deleted file mode 100644 index aacb647e..00000000 --- a/024-abstraction-unit-test/01-start-provider/lib/main.dart +++ /dev/null @@ -1,115 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MultiProvider( - providers: [], - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/024-abstraction-unit-test/01-start-provider/lib/providers_setup.dart b/024-abstraction-unit-test/01-start-provider/lib/providers_setup.dart deleted file mode 100644 index b168209c..00000000 --- a/024-abstraction-unit-test/01-start-provider/lib/providers_setup.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:abstraction_unit/services/api.dart'; -import 'package:abstraction_unit/services/localstorage_service.dart'; -import 'package:provider/provider.dart'; -import 'package:provider/single_child_widget.dart'; - -List providers = [ - Provider.value(value: LocalStorageService()), - Provider.value( - value: Api(), - ) -]; diff --git a/024-abstraction-unit-test/01-start-provider/lib/services/api.dart b/024-abstraction-unit-test/01-start-provider/lib/services/api.dart deleted file mode 100644 index 02058634..00000000 --- a/024-abstraction-unit-test/01-start-provider/lib/services/api.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:http/http.dart' as http; - -class Api { - static const endpoint = 'https://myapi.com'; - - var client = new http.Client(); - - Future likePost(int postId) async { - var response = - await client.post('$endpoint/likePost/$postId'); - - if(response.statusCode == 200) { - return true; - } - - return false; - } -} diff --git a/024-abstraction-unit-test/01-start-provider/lib/services/localstorage_service.dart b/024-abstraction-unit-test/01-start-provider/lib/services/localstorage_service.dart deleted file mode 100644 index 43cf7c88..00000000 --- a/024-abstraction-unit-test/01-start-provider/lib/services/localstorage_service.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:async'; - -import 'package:abstraction_unit/datamodels/post.dart'; -import 'package:localstorage/localstorage.dart'; - -class LocalStorageService { - final LocalStorage _postsStorage = new LocalStorage('postsStorage'); - final StreamController _postUpdated = StreamController.broadcast(); - - Stream get postUpdateStream => _postUpdated.stream; - - Future likePost(int postId, {bool unlike = false}) async { - // Get all the current posts - Map data = _postsStorage.getItem('user_posts'); - - // check if the one we're liking is in the collection - if (data.containsKey('$postId')) { - // convert to a post - var post = Post.fromMap(data['$postId']); - - if (!unlike) { - // increment like count - post.likeCount++; - } else { - // decrement like count - post.likeCount--; - } - // change back to map and save to the data - data['$postId'] = post.toMap(); - // save all the data back to the local storage - await _postsStorage.setItem('user_posts', data); - // indicate the post Id has updated so the widget can reload itself - _postUpdated.add(postId); - return true; - } else { - print('Data for post $postId is not on disk. Add from api after fetch.'); - return false; - } - } - - void dispose() { - _postUpdated.close(); - } -} diff --git a/024-abstraction-unit-test/01-start-provider/lib/services/post_service.dart b/024-abstraction-unit-test/01-start-provider/lib/services/post_service.dart deleted file mode 100644 index f52bc6d3..00000000 --- a/024-abstraction-unit-test/01-start-provider/lib/services/post_service.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:abstraction_unit/services/localstorage_service.dart'; -import 'api.dart'; - -class PostService { - Api _api; - LocalStorageService _localStorageService; - - PostService({Api api, LocalStorageService localStorageService}) - : _api = api, - _localStorageService = localStorageService; - - Future likePost(int postId) async { - var localLikeSuccess = await _localStorageService.likePost(postId); - var postLiked = await _api.likePost(postId); - - if (postLiked) { - return true; - } - - if (localLikeSuccess) { - await _localStorageService.likePost(postId, unlike: true); - } - - return false; - } -} diff --git a/024-abstraction-unit-test/01-start-provider/pubspec.lock b/024-abstraction-unit-test/01-start-provider/pubspec.lock deleted file mode 100644 index 736e3059..00000000 --- a/024-abstraction-unit-test/01-start-provider/pubspec.lock +++ /dev/null @@ -1,259 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - localstorage: - dependency: "direct main" - description: - name: localstorage - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2+5" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+1" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+3" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.13" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.0" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/024-abstraction-unit-test/01-start-provider/pubspec.yaml b/024-abstraction-unit-test/01-start-provider/pubspec.yaml deleted file mode 100644 index dbcd5555..00000000 --- a/024-abstraction-unit-test/01-start-provider/pubspec.yaml +++ /dev/null @@ -1,69 +0,0 @@ -name: abstraction_unit -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - http: - provider: ^4.1.3 - localstorage: ^3.0.2+5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/024-abstraction-unit-test/01-start-provider/test/postservice_test.dart b/024-abstraction-unit-test/01-start-provider/test/postservice_test.dart deleted file mode 100644 index 1eafd304..00000000 --- a/024-abstraction-unit-test/01-start-provider/test/postservice_test.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:abstraction_unit/services/post_service.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - group('PostService Test | ', () { - test('Constructing Service should find correct dependencies', () { - var postService = PostService(); - expect(postService != null, true); - }); - }); -} diff --git a/024-abstraction-unit-test/02-final-getit/.flutter-plugins-dependencies b/024-abstraction-unit-test/02-final-getit/.flutter-plugins-dependencies deleted file mode 100644 index 5accd22b..00000000 --- a/024-abstraction-unit-test/02-final-getit/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+1/","dependencies":[]}],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]}],"date_created":"2020-06-18 21:49:34.871499","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/024-abstraction-unit-test/02-final-getit/.gitignore b/024-abstraction-unit-test/02-final-getit/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/024-abstraction-unit-test/02-final-getit/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/024-abstraction-unit-test/02-final-getit/.metadata b/024-abstraction-unit-test/02-final-getit/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/024-abstraction-unit-test/02-final-getit/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/024-abstraction-unit-test/02-final-getit/README.md b/024-abstraction-unit-test/02-final-getit/README.md deleted file mode 100644 index e3a8ac68..00000000 --- a/024-abstraction-unit-test/02-final-getit/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# abstraction_unit - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/024-abstraction-unit-test/02-final-getit/lib/datamodels/post.dart b/024-abstraction-unit-test/02-final-getit/lib/datamodels/post.dart deleted file mode 100644 index 4d2a97b8..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/datamodels/post.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Post { - String title; - int likeCount; - - Post({this.title, this.likeCount}); - - Post.fromMap(Map map) { - title = map['title']; - likeCount = map['likeCount']; - } - - Map toMap() { - var map = {'title': title, 'likeCount': likeCount}; - return map; - } -} diff --git a/024-abstraction-unit-test/02-final-getit/lib/locator.dart b/024-abstraction-unit-test/02-final-getit/lib/locator.dart deleted file mode 100644 index eb36860d..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/locator.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:abstraction_unit/services/api/http_api.dart'; -import 'package:abstraction_unit/services/storage/localstorage_service.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => HttpApi()); - locator.registerLazySingleton(() => LocalStorageService()); -} diff --git a/024-abstraction-unit-test/02-final-getit/lib/main.dart b/024-abstraction-unit-test/02-final-getit/lib/main.dart deleted file mode 100644 index cc192a57..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/main.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/024-abstraction-unit-test/02-final-getit/lib/services/api/api.dart b/024-abstraction-unit-test/02-final-getit/lib/services/api/api.dart deleted file mode 100644 index b5c04e5c..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/services/api/api.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract class Api { - Future likePost(int postId); -} diff --git a/024-abstraction-unit-test/02-final-getit/lib/services/api/http_api.dart b/024-abstraction-unit-test/02-final-getit/lib/services/api/http_api.dart deleted file mode 100644 index 46c58630..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/services/api/http_api.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:http/http.dart' as http; - -class HttpApi implements Api { - static const endpoint = 'https://myapi.com'; - - var client = new http.Client(); - - @override - Future likePost(int postId) async { - var response = - await client.post('$endpoint/likePost/$postId'); - - if(response.statusCode == 200) { - return true; - } - - return false; - } -} diff --git a/024-abstraction-unit-test/02-final-getit/lib/services/post_service.dart b/024-abstraction-unit-test/02-final-getit/lib/services/post_service.dart deleted file mode 100644 index 9ba23606..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/services/post_service.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:abstraction_unit/locator.dart'; -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; - -class PostService { - Api _api = locator(); - StorageService _localStorageService = locator(); - - Future likePost(int postId) async { - var localLikeSuccess = await _localStorageService.likePost(postId); - var postLiked = await _api.likePost(postId); - - if (postLiked) { - return true; - } - - // TODO: Revert the local like - if (localLikeSuccess) { - await _localStorageService.likePost(postId, unlike: true); - } - - return false; - } -} diff --git a/024-abstraction-unit-test/02-final-getit/lib/services/storage/localstorage_service.dart b/024-abstraction-unit-test/02-final-getit/lib/services/storage/localstorage_service.dart deleted file mode 100644 index 2efc274d..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/services/storage/localstorage_service.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'dart:async'; - -import 'package:abstraction_unit/datamodels/post.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; -import 'package:localstorage/localstorage.dart'; - -class LocalStorageService implements StorageService { - final LocalStorage _postsStorage = new LocalStorage('postsStorage'); - final StreamController _postUpdated = StreamController.broadcast(); - - @override - Stream get postUpdateStream => _postUpdated.stream; - - @override - Future likePost(int postId, {bool unlike = false}) async { - // Get all the current posts - Map data = _postsStorage.getItem('user_posts'); - - // check if the one we're liking is in the collection - if (data.containsKey('$postId')) { - // convert to a post - var post = Post.fromMap(data['$postId']); - - if (!unlike) { - // increment like count - post.likeCount++; - } else { - // decrement like count - post.likeCount--; - } - // change back to map and save to the data - data['$postId'] = post.toMap(); - // save all the data back to the local storage - await _postsStorage.setItem('user_posts', data); - // indicate the post Id has updated so the widget can reload itself - _postUpdated.add(postId); - return true; - } else { - print('Data for post $postId is not on disk. Add from api after fetch.'); - return false; - } - } - - @override - void dispose() { - _postUpdated.close(); - } -} diff --git a/024-abstraction-unit-test/02-final-getit/lib/services/storage/storage_service.dart b/024-abstraction-unit-test/02-final-getit/lib/services/storage/storage_service.dart deleted file mode 100644 index 3f91f515..00000000 --- a/024-abstraction-unit-test/02-final-getit/lib/services/storage/storage_service.dart +++ /dev/null @@ -1,7 +0,0 @@ -abstract class StorageService { - Stream get postUpdateStream; - - Future likePost(int postId, {bool unlike = false}); - - void dispose(); -} \ No newline at end of file diff --git a/024-abstraction-unit-test/02-final-getit/pubspec.lock b/024-abstraction-unit-test/02-final-getit/pubspec.lock deleted file mode 100644 index 26c9bc6a..00000000 --- a/024-abstraction-unit-test/02-final-getit/pubspec.lock +++ /dev/null @@ -1,259 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - localstorage: - dependency: "direct main" - description: - name: localstorage - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2+5" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - mockito: - dependency: "direct dev" - description: - name: mockito - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.1" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+1" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+3" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.13" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.0" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/024-abstraction-unit-test/02-final-getit/pubspec.yaml b/024-abstraction-unit-test/02-final-getit/pubspec.yaml deleted file mode 100644 index e877ae08..00000000 --- a/024-abstraction-unit-test/02-final-getit/pubspec.yaml +++ /dev/null @@ -1,70 +0,0 @@ -name: abstraction_unit -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - http: - get_it: - localstorage: ^3.0.2+5 - -dev_dependencies: - flutter_test: - sdk: flutter - mockito: ^4.1.1 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/024-abstraction-unit-test/02-final-getit/test/postservice_test.dart b/024-abstraction-unit-test/02-final-getit/test/postservice_test.dart deleted file mode 100644 index 312baaaa..00000000 --- a/024-abstraction-unit-test/02-final-getit/test/postservice_test.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:abstraction_unit/locator.dart'; -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:abstraction_unit/services/post_service.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -class MockStorageService extends Mock implements StorageService {} - -class MockApi extends Mock implements Api {} - -void main() { - group('PostService Test | ', () { - setUpAll(() { - setupLocator(); - locator.allowReassignment = true; - }); - - test('Constructing Service should find correct dependencies', () { - var postService = PostService(); - expect(postService != null, true); - }); - - test('Given postId 1, should call localStorageService with 1', () async { - var mockStorageService = MockStorageService(); - locator.registerSingleton(mockStorageService); - - var mockApi = MockApi(); - when(mockApi.likePost(1)).thenAnswer((_) => Future.value(true)); - locator.registerSingleton(mockApi); - - var postService = PostService(); - await postService.likePost(1); - verify(mockStorageService.likePost(1)); - }); - }); -} diff --git a/024-abstraction-unit-test/02-final-provider/.flutter-plugins-dependencies b/024-abstraction-unit-test/02-final-provider/.flutter-plugins-dependencies deleted file mode 100644 index 9f2aca03..00000000 --- a/024-abstraction-unit-test/02-final-provider/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.11/","dependencies":[]}],"macos":[{"name":"path_provider_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+3/","dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+1/","dependencies":[]}],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_macos","path_provider_linux"]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_macos","dependencies":[]}],"date_created":"2020-06-18 21:49:33.311283","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/024-abstraction-unit-test/02-final-provider/.gitignore b/024-abstraction-unit-test/02-final-provider/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/024-abstraction-unit-test/02-final-provider/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/024-abstraction-unit-test/02-final-provider/.metadata b/024-abstraction-unit-test/02-final-provider/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/024-abstraction-unit-test/02-final-provider/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/024-abstraction-unit-test/02-final-provider/README.md b/024-abstraction-unit-test/02-final-provider/README.md deleted file mode 100644 index e3a8ac68..00000000 --- a/024-abstraction-unit-test/02-final-provider/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# abstraction_unit - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/024-abstraction-unit-test/02-final-provider/lib/datamodels/post.dart b/024-abstraction-unit-test/02-final-provider/lib/datamodels/post.dart deleted file mode 100644 index 4d2a97b8..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/datamodels/post.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Post { - String title; - int likeCount; - - Post({this.title, this.likeCount}); - - Post.fromMap(Map map) { - title = map['title']; - likeCount = map['likeCount']; - } - - Map toMap() { - var map = {'title': title, 'likeCount': likeCount}; - return map; - } -} diff --git a/024-abstraction-unit-test/02-final-provider/lib/main.dart b/024-abstraction-unit-test/02-final-provider/lib/main.dart deleted file mode 100644 index aacb647e..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/main.dart +++ /dev/null @@ -1,115 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MultiProvider( - providers: [], - child: MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. - primarySwatch: Colors.blue, - ), - home: MyHomePage(title: 'Flutter Demo Home Page'), - ), - ); - } -} - -class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State { - int _counter = 0; - - void _incrementCounter() { - setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. - _counter++; - }); - } - - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text(widget.title), - ), - body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: Column( - // Column is also layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'You have pushed the button this many times:', - ), - Text( - '$_counter', - style: Theme.of(context).textTheme.headline4, - ), - ], - ), - ), - floatingActionButton: FloatingActionButton( - onPressed: _incrementCounter, - tooltip: 'Increment', - child: Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. - ); - } -} diff --git a/024-abstraction-unit-test/02-final-provider/lib/providers_setup.dart b/024-abstraction-unit-test/02-final-provider/lib/providers_setup.dart deleted file mode 100644 index 65a1ef7a..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/providers_setup.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:abstraction_unit/services/api/http_api.dart'; -import 'package:abstraction_unit/services/storage/localstorage_service.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; -import 'package:provider/provider.dart'; -import 'package:provider/single_child_widget.dart'; - -List providers = [ - Provider.value(value: LocalStorageService()), - Provider.value(value: HttpApi()) -]; diff --git a/024-abstraction-unit-test/02-final-provider/lib/services/api/api.dart b/024-abstraction-unit-test/02-final-provider/lib/services/api/api.dart deleted file mode 100644 index b5c04e5c..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/services/api/api.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract class Api { - Future likePost(int postId); -} diff --git a/024-abstraction-unit-test/02-final-provider/lib/services/api/http_api.dart b/024-abstraction-unit-test/02-final-provider/lib/services/api/http_api.dart deleted file mode 100644 index 46c58630..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/services/api/http_api.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:http/http.dart' as http; - -class HttpApi implements Api { - static const endpoint = 'https://myapi.com'; - - var client = new http.Client(); - - @override - Future likePost(int postId) async { - var response = - await client.post('$endpoint/likePost/$postId'); - - if(response.statusCode == 200) { - return true; - } - - return false; - } -} diff --git a/024-abstraction-unit-test/02-final-provider/lib/services/post_service.dart b/024-abstraction-unit-test/02-final-provider/lib/services/post_service.dart deleted file mode 100644 index 8fb0d8dc..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/services/post_service.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; - -class PostService { - final Api _api; - final StorageService _storageService; - - PostService({ - Api api, - StorageService storageService, - }) : _api = api, - _storageService = storageService; - - Future likePost(int postId) async { - var localLikeSuccess = await _storageService.likePost(postId); - var postLiked = await _api.likePost(postId); - - if (postLiked) { - return true; - } - - // TODO: Revert the local like - if (localLikeSuccess) { - await _storageService.likePost(postId, unlike: true); - } - - return false; - } -} diff --git a/024-abstraction-unit-test/02-final-provider/lib/services/storage/localstorage_service.dart b/024-abstraction-unit-test/02-final-provider/lib/services/storage/localstorage_service.dart deleted file mode 100644 index 2efc274d..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/services/storage/localstorage_service.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'dart:async'; - -import 'package:abstraction_unit/datamodels/post.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; -import 'package:localstorage/localstorage.dart'; - -class LocalStorageService implements StorageService { - final LocalStorage _postsStorage = new LocalStorage('postsStorage'); - final StreamController _postUpdated = StreamController.broadcast(); - - @override - Stream get postUpdateStream => _postUpdated.stream; - - @override - Future likePost(int postId, {bool unlike = false}) async { - // Get all the current posts - Map data = _postsStorage.getItem('user_posts'); - - // check if the one we're liking is in the collection - if (data.containsKey('$postId')) { - // convert to a post - var post = Post.fromMap(data['$postId']); - - if (!unlike) { - // increment like count - post.likeCount++; - } else { - // decrement like count - post.likeCount--; - } - // change back to map and save to the data - data['$postId'] = post.toMap(); - // save all the data back to the local storage - await _postsStorage.setItem('user_posts', data); - // indicate the post Id has updated so the widget can reload itself - _postUpdated.add(postId); - return true; - } else { - print('Data for post $postId is not on disk. Add from api after fetch.'); - return false; - } - } - - @override - void dispose() { - _postUpdated.close(); - } -} diff --git a/024-abstraction-unit-test/02-final-provider/lib/services/storage/storage_service.dart b/024-abstraction-unit-test/02-final-provider/lib/services/storage/storage_service.dart deleted file mode 100644 index 3f91f515..00000000 --- a/024-abstraction-unit-test/02-final-provider/lib/services/storage/storage_service.dart +++ /dev/null @@ -1,7 +0,0 @@ -abstract class StorageService { - Stream get postUpdateStream; - - Future likePost(int postId, {bool unlike = false}); - - void dispose(); -} \ No newline at end of file diff --git a/024-abstraction-unit-test/02-final-provider/pubspec.lock b/024-abstraction-unit-test/02-final-provider/pubspec.lock deleted file mode 100644 index 1a233415..00000000 --- a/024-abstraction-unit-test/02-final-provider/pubspec.lock +++ /dev/null @@ -1,385 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "50.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.1" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - build: - dependency: transitive - description: - name: build - url: "https://pub.dartlang.org" - source: hosted - version: "2.3.1" - built_collection: - dependency: transitive - description: - name: built_collection - url: "https://pub.dartlang.org" - source: hosted - version: "5.1.1" - built_value: - dependency: transitive - description: - name: built_value - url: "https://pub.dartlang.org" - source: hosted - version: "8.4.2" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - code_builder: - dependency: transitive - description: - name: code_builder - url: "https://pub.dartlang.org" - source: hosted - version: "4.3.0" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - dart_style: - dependency: transitive - description: - name: dart_style - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.4" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.4" - fixnum: - dependency: transitive - description: - name: fixnum - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - localstorage: - dependency: "direct main" - description: - name: localstorage - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2+5" - logging: - dependency: transitive - description: - name: logging - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - mockito: - dependency: "direct dev" - description: - name: mockito - url: "https://pub.dartlang.org" - source: hosted - version: "5.3.2" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+1" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+3" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.6" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" -sdks: - dart: ">=2.18.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/024-abstraction-unit-test/02-final-provider/pubspec.yaml b/024-abstraction-unit-test/02-final-provider/pubspec.yaml deleted file mode 100644 index 3451eb0a..00000000 --- a/024-abstraction-unit-test/02-final-provider/pubspec.yaml +++ /dev/null @@ -1,70 +0,0 @@ -name: abstraction_unit -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - http: any - provider: ^4.1.3 - localstorage: ^3.0.2+5 - -dev_dependencies: - flutter_test: - sdk: flutter - mockito: ">=4.1.1 <6.0.0" - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/024-abstraction-unit-test/02-final-provider/test/postservice_test.dart b/024-abstraction-unit-test/02-final-provider/test/postservice_test.dart deleted file mode 100644 index 8c081592..00000000 --- a/024-abstraction-unit-test/02-final-provider/test/postservice_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:abstraction_unit/services/api/api.dart'; -import 'package:abstraction_unit/services/post_service.dart'; -import 'package:abstraction_unit/services/storage/storage_service.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; - -class MockStorageService extends Mock implements StorageService {} - -class MockApi extends Mock implements Api {} - -void main() { - group('PostService Test | ', () { - test('Constructing Service should find correct dependencies', () { - var postService = PostService(); - expect(postService != null, true); - }); - - test('Given postId 1, should call localStorageService with 1', () async { - var storageService = MockStorageService(); - - var mockApi = MockApi(); - when(mockApi.likePost(1)).thenAnswer((_) => Future.value(true)); - - var postService = - PostService(api: mockApi, storageService: storageService); - await postService.likePost(1); - verify(storageService.likePost(1)); - }); - }); -} diff --git a/025-navigation-service/01-start/.gitignore b/025-navigation-service/01-start/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/025-navigation-service/01-start/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/025-navigation-service/01-start/.metadata b/025-navigation-service/01-start/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/025-navigation-service/01-start/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/025-navigation-service/01-start/README.md b/025-navigation-service/01-start/README.md deleted file mode 100644 index 29ed022a..00000000 --- a/025-navigation-service/01-start/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# nav_service - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/025-navigation-service/01-start/lib/constants/route_paths.dart b/025-navigation-service/01-start/lib/constants/route_paths.dart deleted file mode 100644 index 5f34e09d..00000000 --- a/025-navigation-service/01-start/lib/constants/route_paths.dart +++ /dev/null @@ -1,2 +0,0 @@ -const String LoginRoute = 'Login'; -const String HomeRoute = 'Home'; diff --git a/025-navigation-service/01-start/lib/locator.dart b/025-navigation-service/01-start/lib/locator.dart deleted file mode 100644 index f8f137be..00000000 --- a/025-navigation-service/01-start/lib/locator.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:get_it/get_it.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - -} \ No newline at end of file diff --git a/025-navigation-service/01-start/lib/main.dart b/025-navigation-service/01-start/lib/main.dart deleted file mode 100644 index 48443e8b..00000000 --- a/025-navigation-service/01-start/lib/main.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:nav_service/constants/route_paths.dart' as routes; -import 'package:nav_service/locator.dart'; -import 'package:nav_service/router.dart' as router; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - backgroundColor: Colors.grey[800] - ), - onGenerateRoute: router.generateRoute, - initialRoute: routes.LoginRoute, - ); - } -} diff --git a/025-navigation-service/01-start/lib/router.dart b/025-navigation-service/01-start/lib/router.dart deleted file mode 100644 index 3a8e879c..00000000 --- a/025-navigation-service/01-start/lib/router.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:nav_service/constants/route_paths.dart' as routes; -import 'package:nav_service/views/home_view.dart'; -import 'package:nav_service/views/login_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case routes.LoginRoute: - return MaterialPageRoute(builder: (context) => LoginView()); - case routes.HomeRoute: - return MaterialPageRoute(builder: (context) => HomeView()); - default: - return MaterialPageRoute( - builder: (context) => Scaffold( - body: Center( - child: Text('No path for ${settings.name}'), - ), - ), - ); - } -} diff --git a/025-navigation-service/01-start/lib/viewmodels/basemodel.dart b/025-navigation-service/01-start/lib/viewmodels/basemodel.dart deleted file mode 100644 index 4c09c1e2..00000000 --- a/025-navigation-service/01-start/lib/viewmodels/basemodel.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/cupertino.dart'; - -class BaseModel extends ChangeNotifier { - bool _busy = false; - String _errorMessage; - - bool get busy => _busy; - String get errorMessage => _errorMessage; - bool get hasErrorMessage => _errorMessage != null && _errorMessage.isNotEmpty; - - void setErrorMessage(String message) { - _errorMessage = message; - notifyListeners(); - } - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/025-navigation-service/01-start/lib/viewmodels/home_viewmodel.dart b/025-navigation-service/01-start/lib/viewmodels/home_viewmodel.dart deleted file mode 100644 index 8e8b7b03..00000000 --- a/025-navigation-service/01-start/lib/viewmodels/home_viewmodel.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:nav_service/viewmodels/basemodel.dart'; - -class HomeViewModel extends BaseModel { - Future logout({bool success = true}) async { - setBusy(true); - await Future.delayed(Duration(seconds: 1)); - - if (!success) { - setErrorMessage('Error has occured during sign out'); - } else { - setErrorMessage(null); - } - - setBusy(false); - return success; - } -} diff --git a/025-navigation-service/01-start/lib/viewmodels/login_viewmodel.dart b/025-navigation-service/01-start/lib/viewmodels/login_viewmodel.dart deleted file mode 100644 index a6df6059..00000000 --- a/025-navigation-service/01-start/lib/viewmodels/login_viewmodel.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:nav_service/viewmodels/basemodel.dart'; - -class LoginViewModel extends BaseModel { - Future login({bool success = true}) async { - setBusy(true); - await Future.delayed(Duration(seconds: 1)); - - if (!success) { - setErrorMessage('Error has occured with the login'); - } else { - setErrorMessage(null); - } - - setBusy(false); - return success; - } -} diff --git a/025-navigation-service/01-start/lib/views/home_view.dart b/025-navigation-service/01-start/lib/views/home_view.dart deleted file mode 100644 index 3148df72..00000000 --- a/025-navigation-service/01-start/lib/views/home_view.dart +++ /dev/null @@ -1,70 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:nav_service/viewmodels/home_viewmodel.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => HomeViewModel(), - child: Consumer( - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.only(bottom: 25.0), - child: Align( - alignment: Alignment.bottomCenter, - child: GestureDetector( - onTap: () async { - var success = await model.logout(); - if (success) { - Navigator.of(context).pop(); - } - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - model.hasErrorMessage - ? Text( - model.errorMessage, - style: TextStyle( - color: Colors.red[800], - fontSize: 20, - fontWeight: FontWeight.w300, - ), - ) - : Container(), - Container( - width: 200, - height: 80, - alignment: Alignment.center, - child: !model.busy - ? Text('Logout', - style: TextStyle( - fontWeight: FontWeight.w800, - color: Colors.white, - fontSize: 30)) - : CircularProgressIndicator(), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: Colors.blue[200], - blurRadius: 8, - spreadRadius: 2, - ) - ], - ), - ), - ], - ), - ), - ), - ), - ), - ), - ); - } -} diff --git a/025-navigation-service/01-start/lib/views/login_view.dart b/025-navigation-service/01-start/lib/views/login_view.dart deleted file mode 100644 index 0b3d81c1..00000000 --- a/025-navigation-service/01-start/lib/views/login_view.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:nav_service/constants/route_paths.dart' as routes; -import 'package:nav_service/viewmodels/login_viewmodel.dart'; -import 'package:provider/provider.dart'; - -class LoginView extends StatelessWidget { - const LoginView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => LoginViewModel(), - child: Consumer( - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.only(bottom: 25.0), - child: Align( - alignment: Alignment.bottomCenter, - child: GestureDetector( - onTap: () async { - var success = await model.login(success: true); - if (success) { - Navigator.of(context).pushNamed(routes.HomeRoute); - } - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - model.hasErrorMessage - ? Text( - model.errorMessage, - style: TextStyle( - color: Colors.red[800], - fontSize: 20, - fontWeight: FontWeight.w300, - ), - ) - : Container(), - SizedBox( - height: 25, - ), - Container( - width: 200, - height: 80, - alignment: Alignment.center, - child: !model.busy - ? Text('Login', - style: TextStyle( - fontWeight: FontWeight.w800, - color: Colors.white, - fontSize: 30)) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - decoration: BoxDecoration( - color: Colors.red, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: Colors.red[200], - blurRadius: 8, - spreadRadius: 2, - ) - ], - ), - ), - ], - ), - ), - ), - ), - ), - ), - ); - } -} diff --git a/025-navigation-service/01-start/pubspec.lock b/025-navigation-service/01-start/pubspec.lock deleted file mode 100644 index 3e1ebe13..00000000 --- a/025-navigation-service/01-start/pubspec.lock +++ /dev/null @@ -1,168 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/025-navigation-service/01-start/pubspec.yaml b/025-navigation-service/01-start/pubspec.yaml deleted file mode 100644 index 841ba4eb..00000000 --- a/025-navigation-service/01-start/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: nav_service -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - get_it: ^4.0.2 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/025-navigation-service/01-start/test/widget_test.dart b/025-navigation-service/01-start/test/widget_test.dart deleted file mode 100644 index b6ee27e4..00000000 --- a/025-navigation-service/01-start/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:nav_service/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/025-navigation-service/02-final/.gitignore b/025-navigation-service/02-final/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/025-navigation-service/02-final/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/025-navigation-service/02-final/.metadata b/025-navigation-service/02-final/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/025-navigation-service/02-final/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/025-navigation-service/02-final/README.md b/025-navigation-service/02-final/README.md deleted file mode 100644 index 29ed022a..00000000 --- a/025-navigation-service/02-final/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# nav_service - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/025-navigation-service/02-final/lib/constants/route_paths.dart b/025-navigation-service/02-final/lib/constants/route_paths.dart deleted file mode 100644 index 5f34e09d..00000000 --- a/025-navigation-service/02-final/lib/constants/route_paths.dart +++ /dev/null @@ -1,2 +0,0 @@ -const String LoginRoute = 'Login'; -const String HomeRoute = 'Home'; diff --git a/025-navigation-service/02-final/lib/locator.dart b/025-navigation-service/02-final/lib/locator.dart deleted file mode 100644 index 3bcd3854..00000000 --- a/025-navigation-service/02-final/lib/locator.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:nav_service/services/navigation_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); -} diff --git a/025-navigation-service/02-final/lib/main.dart b/025-navigation-service/02-final/lib/main.dart deleted file mode 100644 index 5ee55c7e..00000000 --- a/025-navigation-service/02-final/lib/main.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:nav_service/constants/route_paths.dart' as routes; -import 'package:nav_service/locator.dart'; -import 'package:nav_service/router.dart' as router; -import 'package:nav_service/services/navigation_service.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - backgroundColor: Colors.grey[800] - ), - navigatorKey: locator().navigatorKey, - onGenerateRoute: router.generateRoute, - initialRoute: routes.LoginRoute, - ); - } -} diff --git a/025-navigation-service/02-final/lib/router.dart b/025-navigation-service/02-final/lib/router.dart deleted file mode 100644 index 33f0612f..00000000 --- a/025-navigation-service/02-final/lib/router.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:nav_service/constants/route_paths.dart' as routes; -import 'package:nav_service/views/home_view.dart'; -import 'package:nav_service/views/login_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case routes.LoginRoute: - return MaterialPageRoute(builder: (context) => LoginView()); - case routes.HomeRoute: - var userName = settings.arguments as String; - return MaterialPageRoute( - builder: (context) => HomeView(userName: userName)); - default: - return MaterialPageRoute( - builder: (context) => Scaffold( - body: Center( - child: Text('No path for ${settings.name}'), - ), - ), - ); - } -} diff --git a/025-navigation-service/02-final/lib/services/navigation_service.dart b/025-navigation-service/02-final/lib/services/navigation_service.dart deleted file mode 100644 index 4206873b..00000000 --- a/025-navigation-service/02-final/lib/services/navigation_service.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - final GlobalKey navigatorKey = - new GlobalKey(); - - Future navigateTo(String routeName, {dynamic arguments}) { - return navigatorKey.currentState.pushNamed(routeName, arguments: arguments); - } - - void goBack() { - return navigatorKey.currentState.pop(); - } -} diff --git a/025-navigation-service/02-final/lib/viewmodels/basemodel.dart b/025-navigation-service/02-final/lib/viewmodels/basemodel.dart deleted file mode 100644 index 4c09c1e2..00000000 --- a/025-navigation-service/02-final/lib/viewmodels/basemodel.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/cupertino.dart'; - -class BaseModel extends ChangeNotifier { - bool _busy = false; - String _errorMessage; - - bool get busy => _busy; - String get errorMessage => _errorMessage; - bool get hasErrorMessage => _errorMessage != null && _errorMessage.isNotEmpty; - - void setErrorMessage(String message) { - _errorMessage = message; - notifyListeners(); - } - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/025-navigation-service/02-final/lib/viewmodels/home_viewmodel.dart b/025-navigation-service/02-final/lib/viewmodels/home_viewmodel.dart deleted file mode 100644 index 1f15c1a8..00000000 --- a/025-navigation-service/02-final/lib/viewmodels/home_viewmodel.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:nav_service/locator.dart'; -import 'package:nav_service/viewmodels/basemodel.dart'; -import 'package:nav_service/services/navigation_service.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - - Future logout({bool success = true}) async { - setBusy(true); - await Future.delayed(Duration(seconds: 1)); - - if (!success) { - setErrorMessage('Error has occured during sign out'); - } else { - _navigationService.goBack(); - } - } -} diff --git a/025-navigation-service/02-final/lib/viewmodels/login_viewmodel.dart b/025-navigation-service/02-final/lib/viewmodels/login_viewmodel.dart deleted file mode 100644 index d29ec831..00000000 --- a/025-navigation-service/02-final/lib/viewmodels/login_viewmodel.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:nav_service/constants/route_paths.dart' as routes; -import 'package:nav_service/locator.dart'; -import 'package:nav_service/services/navigation_service.dart'; -import 'package:nav_service/viewmodels/basemodel.dart'; - -class LoginViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - Future login({bool success = true}) async { - setBusy(true); - await Future.delayed(Duration(seconds: 1)); - - if (!success) { - setErrorMessage('Error has occured with the login'); - } else { - _navigationService.navigateTo(routes.HomeRoute, arguments: '\nFilledStacks'); - setErrorMessage(null); - } - - setBusy(false); - } -} diff --git a/025-navigation-service/02-final/lib/views/home_view.dart b/025-navigation-service/02-final/lib/views/home_view.dart deleted file mode 100644 index bac64dd3..00000000 --- a/025-navigation-service/02-final/lib/views/home_view.dart +++ /dev/null @@ -1,68 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:nav_service/viewmodels/home_viewmodel.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - final String userName; - const HomeView({Key key, this.userName}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => HomeViewModel(), - child: Consumer( - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.only(bottom: 25.0), - child: Align( - alignment: Alignment.bottomCenter, - child: GestureDetector( - onTap: () { - model.logout(); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - model.hasErrorMessage - ? Text( - model.errorMessage, - style: TextStyle( - color: Colors.red[800], - fontSize: 20, - fontWeight: FontWeight.w300, - ), - ) - : Container(), - Container( - width: 200, - height: 80, - alignment: Alignment.center, - child: !model.busy - ? Text('Logout' + userName, - style: TextStyle( - fontWeight: FontWeight.w800, - color: Colors.white, - fontSize: 30)) - : CircularProgressIndicator(), - decoration: BoxDecoration( - color: Colors.blue, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: Colors.blue[200], - blurRadius: 8, - spreadRadius: 2, - ) - ], - ), - ), - ], - ), - ), - ), - ), - ), - ), - ); - } -} diff --git a/025-navigation-service/02-final/lib/views/login_view.dart b/025-navigation-service/02-final/lib/views/login_view.dart deleted file mode 100644 index f3b7b5cd..00000000 --- a/025-navigation-service/02-final/lib/views/login_view.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:nav_service/viewmodels/login_viewmodel.dart'; -import 'package:provider/provider.dart'; - -class LoginView extends StatelessWidget { - const LoginView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => LoginViewModel(), - child: Consumer( - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.only(bottom: 25.0), - child: Align( - alignment: Alignment.bottomCenter, - child: GestureDetector( - onTap: () { - model.login(success: true); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - model.hasErrorMessage - ? Text( - model.errorMessage, - style: TextStyle( - color: Colors.red[800], - fontSize: 20, - fontWeight: FontWeight.w300, - ), - ) - : Container(), - SizedBox( - height: 25, - ), - Container( - width: 200, - height: 80, - alignment: Alignment.center, - child: !model.busy - ? Text('Login', - style: TextStyle( - fontWeight: FontWeight.w800, - color: Colors.white, - fontSize: 30)) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - decoration: BoxDecoration( - color: Colors.red, - borderRadius: BorderRadius.circular(10), - boxShadow: [ - BoxShadow( - color: Colors.red[200], - blurRadius: 8, - spreadRadius: 2, - ) - ], - ), - ), - ], - ), - ), - ), - ), - ), - ), - ); - } -} diff --git a/025-navigation-service/02-final/pubspec.lock b/025-navigation-service/02-final/pubspec.lock deleted file mode 100644 index 3e1ebe13..00000000 --- a/025-navigation-service/02-final/pubspec.lock +++ /dev/null @@ -1,168 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/025-navigation-service/02-final/pubspec.yaml b/025-navigation-service/02-final/pubspec.yaml deleted file mode 100644 index 841ba4eb..00000000 --- a/025-navigation-service/02-final/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: nav_service -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - get_it: ^4.0.2 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/025-navigation-service/02-final/test/widget_test.dart b/025-navigation-service/02-final/test/widget_test.dart deleted file mode 100644 index b6ee27e4..00000000 --- a/025-navigation-service/02-final/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:nav_service/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/026-stream-basics/.gitignore b/026-stream-basics/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/026-stream-basics/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/026-stream-basics/.metadata b/026-stream-basics/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/026-stream-basics/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/026-stream-basics/README.md b/026-stream-basics/README.md deleted file mode 100644 index 9eca8196..00000000 --- a/026-stream-basics/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Stream Guide - -The final source for the follow along tutorial. \ No newline at end of file diff --git a/026-stream-basics/lib/main.dart b/026-stream-basics/lib/main.dart deleted file mode 100644 index d0a70257..00000000 --- a/026-stream-basics/lib/main.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'dart:async'; -import 'dart:math'; - -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatefulWidget { - @override - _MyAppState createState() => _MyAppState(); -} - -class _MyAppState extends State { - StreamController controller = StreamController(); - StreamSubscription streamSubscription; - - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - home: Scaffold( - body: Center( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - MaterialButton( - child: Text('Subscribe'), - color: Colors.yellow, - onPressed: () async { - getDelayedRandomValue().listen((value) { - print('Value from manualStream: $value'); - }); - }, - ), - MaterialButton( - child: Text('Emit Value'), - color: Colors.blue[200], - onPressed: () { - controller.add(12); - }, - ), - MaterialButton( - child: Text('Unsubscribe'), - color: Colors.red[200], - onPressed: () { - streamSubscription?.cancel(); - }, - ) - ], - ), - ), - )); - } - - Stream getDelayedRandomValue() async* { - var random = Random(); - - while (true) { - await Future.delayed(Duration(seconds: 1)); - yield random.nextDouble(); - } - } -} diff --git a/026-stream-basics/pubspec.lock b/026-stream-basics/pubspec.lock deleted file mode 100644 index 066a096b..00000000 --- a/026-stream-basics/pubspec.lock +++ /dev/null @@ -1,146 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/026-stream-basics/pubspec.yaml b/026-stream-basics/pubspec.yaml deleted file mode 100644 index 106b8626..00000000 --- a/026-stream-basics/pubspec.yaml +++ /dev/null @@ -1,66 +0,0 @@ -name: stream_guide -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/026-stream-basics/test/widget_test.dart b/026-stream-basics/test/widget_test.dart deleted file mode 100644 index e2bfea08..00000000 --- a/026-stream-basics/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:stream_guide/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/027-location-service/.flutter-plugins-dependencies b/027-location-service/.flutter-plugins-dependencies deleted file mode 100644 index 8875fe83..00000000 --- a/027-location-service/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"location","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/location-3.0.2/","dependencies":[]}],"android":[{"name":"location","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/location-3.0.2/","dependencies":[]}],"macos":[{"name":"location","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/location-3.0.2/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"location_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/location_web-1.0.0/","dependencies":[]}]},"dependencyGraph":[{"name":"location","dependencies":["location_web"]},{"name":"location_web","dependencies":[]}],"date_created":"2020-06-18 21:49:50.804133","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/027-location-service/.gitignore b/027-location-service/.gitignore deleted file mode 100644 index aa35107b..00000000 --- a/027-location-service/.gitignore +++ /dev/null @@ -1,72 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/027-location-service/.metadata b/027-location-service/.metadata deleted file mode 100644 index d92e89ac..00000000 --- a/027-location-service/.metadata +++ /dev/null @@ -1,10 +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: 20e59316b8b8474554b38493b8ca888794b0234a - channel: stable - -project_type: app diff --git a/027-location-service/README.md b/027-location-service/README.md deleted file mode 100644 index 2d8efc8b..00000000 --- a/027-location-service/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# location_service - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/027-location-service/lib/datamodels/user_location.dart b/027-location-service/lib/datamodels/user_location.dart deleted file mode 100644 index 0c3ee084..00000000 --- a/027-location-service/lib/datamodels/user_location.dart +++ /dev/null @@ -1,6 +0,0 @@ -class UserLocation { - final double latitude; - final double longitude; - - UserLocation({this.latitude, this.longitude}); -} diff --git a/027-location-service/lib/main.dart b/027-location-service/lib/main.dart deleted file mode 100644 index 7e6a01a8..00000000 --- a/027-location-service/lib/main.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:location_service/services/location_service.dart'; -import 'package:location_service/views/home_view.dart'; -import 'package:provider/provider.dart'; - -import 'datamodels/user_location.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return StreamProvider( - create: (context) => LocationService().locationStream, - child: MaterialApp(title: 'Flutter Demo', home: HomeView())); - } -} diff --git a/027-location-service/lib/providers.dart b/027-location-service/lib/providers.dart deleted file mode 100644 index e69de29b..00000000 diff --git a/027-location-service/lib/services/location_service.dart b/027-location-service/lib/services/location_service.dart deleted file mode 100644 index 2d78455b..00000000 --- a/027-location-service/lib/services/location_service.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:async'; - -import 'package:location/location.dart'; -import 'package:location_service/datamodels/user_location.dart'; - -class LocationService { - // Keep track of current Location - UserLocation _currentLocation; - Location location = Location(); - // Continuously emit location updates - StreamController _locationController = - StreamController.broadcast(); - - LocationService() { - location.requestPermission().then((granted) { - if (granted == PermissionStatus.granted) { - location.onLocationChanged.listen((locationData) { - if (locationData != null) { - _locationController.add(UserLocation( - latitude: locationData.latitude, - longitude: locationData.longitude, - )); - } - }); - } - }); - } - - Stream get locationStream => _locationController.stream; - - Future getLocation() async { - try { - var userLocation = await location.getLocation(); - _currentLocation = UserLocation( - latitude: userLocation.latitude, - longitude: userLocation.longitude, - ); - } catch (e) { - print('Could not get the location: $e'); - } - - return _currentLocation; - } -} diff --git a/027-location-service/lib/views/home_view.dart b/027-location-service/lib/views/home_view.dart deleted file mode 100644 index c2779293..00000000 --- a/027-location-service/lib/views/home_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:location_service/datamodels/user_location.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var userLocation = Provider.of(context); - return Scaffold( - body: Center( - child: Text( - 'Location: Lat:${userLocation.latitude}, Long: ${userLocation.longitude}'), - ), - ); - } -} diff --git a/027-location-service/pubspec.lock b/027-location-service/pubspec.lock deleted file mode 100644 index 9d7f4e65..00000000 --- a/027-location-service/pubspec.lock +++ /dev/null @@ -1,208 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.2" - location: - dependency: "direct main" - description: - name: location - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - location_platform_interface: - dependency: transitive - description: - name: location_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - location_web: - dependency: transitive - description: - name: location_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/027-location-service/pubspec.yaml b/027-location-service/pubspec.yaml deleted file mode 100644 index bc1eacc0..00000000 --- a/027-location-service/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: location_service -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - location: ^3.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/027-location-service/test/widget_test.dart b/027-location-service/test/widget_test.dart deleted file mode 100644 index 9b8a3e9f..00000000 --- a/027-location-service/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:location_service/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/028-continuous-scroll/01-start/.gitignore b/028-continuous-scroll/01-start/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/028-continuous-scroll/01-start/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/028-continuous-scroll/01-start/.metadata b/028-continuous-scroll/01-start/.metadata deleted file mode 100644 index 4a2a6e1d..00000000 --- a/028-continuous-scroll/01-start/.metadata +++ /dev/null @@ -1,10 +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: 2d2a1ffec95cc70a3218872a2cd3f8de4933c42f - channel: stable - -project_type: app diff --git a/028-continuous-scroll/01-start/README.md b/028-continuous-scroll/01-start/README.md deleted file mode 100644 index f8ed1ed1..00000000 --- a/028-continuous-scroll/01-start/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# continuous_scroll - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/028-continuous-scroll/01-start/lib/main.dart b/028-continuous-scroll/01-start/lib/main.dart deleted file mode 100644 index 80232774..00000000 --- a/028-continuous-scroll/01-start/lib/main.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:continuous_scroll/views/home_view.dart'; -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - home: HomeView(), - ); - } -} diff --git a/028-continuous-scroll/01-start/lib/viewmodels/home_viewmodel.dart b/028-continuous-scroll/01-start/lib/viewmodels/home_viewmodel.dart deleted file mode 100644 index f08a2274..00000000 --- a/028-continuous-scroll/01-start/lib/viewmodels/home_viewmodel.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class HomeViewModel extends ChangeNotifier { - List _items; - List get items => _items; - - HomeViewModel() { - _items = List.generate(15, (index) => 'Title $index'); - } -} diff --git a/028-continuous-scroll/01-start/lib/views/home_view.dart b/028-continuous-scroll/01-start/lib/views/home_view.dart deleted file mode 100644 index c924d8ea..00000000 --- a/028-continuous-scroll/01-start/lib/views/home_view.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:continuous_scroll/viewmodels/home_viewmodel.dart'; -import 'package:continuous_scroll/widgets/list_item.dart'; -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: ChangeNotifierProvider( - create: (context) => HomeViewModel(), - child: Consumer( - builder: (context, model, child) => ListView.builder( - itemCount: model.items.length, - itemBuilder: (context, index) => ListItem( - title: model.items[index], - )), - ), - ), - ); - } -} diff --git a/028-continuous-scroll/01-start/lib/widgets/list_item.dart b/028-continuous-scroll/01-start/lib/widgets/list_item.dart deleted file mode 100644 index 83f0cd05..00000000 --- a/028-continuous-scroll/01-start/lib/widgets/list_item.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class ListItem extends StatelessWidget { - final String title; - const ListItem({Key key, this.title}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 15), - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.grey[400], - ), - ], - borderRadius: BorderRadius.circular(5)), - child: Text(title), - alignment: Alignment.center, - ); - } -} diff --git a/028-continuous-scroll/01-start/pubspec.lock b/028-continuous-scroll/01-start/pubspec.lock deleted file mode 100644 index fda2d6aa..00000000 --- a/028-continuous-scroll/01-start/pubspec.lock +++ /dev/null @@ -1,161 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/028-continuous-scroll/01-start/pubspec.yaml b/028-continuous-scroll/01-start/pubspec.yaml deleted file mode 100644 index 12c70026..00000000 --- a/028-continuous-scroll/01-start/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: continuous_scroll -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/028-continuous-scroll/01-start/test/widget_test.dart b/028-continuous-scroll/01-start/test/widget_test.dart deleted file mode 100644 index 65f38bb8..00000000 --- a/028-continuous-scroll/01-start/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:continuous_scroll/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/028-continuous-scroll/02-final/.gitignore b/028-continuous-scroll/02-final/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/028-continuous-scroll/02-final/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/028-continuous-scroll/02-final/.metadata b/028-continuous-scroll/02-final/.metadata deleted file mode 100644 index 4a2a6e1d..00000000 --- a/028-continuous-scroll/02-final/.metadata +++ /dev/null @@ -1,10 +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: 2d2a1ffec95cc70a3218872a2cd3f8de4933c42f - channel: stable - -project_type: app diff --git a/028-continuous-scroll/02-final/README.md b/028-continuous-scroll/02-final/README.md deleted file mode 100644 index f8ed1ed1..00000000 --- a/028-continuous-scroll/02-final/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# continuous_scroll - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/028-continuous-scroll/02-final/lib/constants/ui_constants.dart b/028-continuous-scroll/02-final/lib/constants/ui_constants.dart deleted file mode 100644 index dc454d7c..00000000 --- a/028-continuous-scroll/02-final/lib/constants/ui_constants.dart +++ /dev/null @@ -1 +0,0 @@ -const String LoadingIndicatorTitle = '^'; diff --git a/028-continuous-scroll/02-final/lib/main.dart b/028-continuous-scroll/02-final/lib/main.dart deleted file mode 100644 index 80232774..00000000 --- a/028-continuous-scroll/02-final/lib/main.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:continuous_scroll/views/home_view.dart'; -import 'package:flutter/material.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - home: HomeView(), - ); - } -} diff --git a/028-continuous-scroll/02-final/lib/viewmodels/home_viewmodel.dart b/028-continuous-scroll/02-final/lib/viewmodels/home_viewmodel.dart deleted file mode 100644 index b87a1700..00000000 --- a/028-continuous-scroll/02-final/lib/viewmodels/home_viewmodel.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:continuous_scroll/constants/ui_constants.dart'; -import 'package:flutter/widgets.dart'; - -class HomeViewModel extends ChangeNotifier { - static const int ItemRequestThreshold = 15; - - List _items; - List get items => _items; - - int _currentPage = 0; - - HomeViewModel() { - _items = List.generate(15, (index) => 'Title $index'); - } - - Future handleItemCreated(int index) async { - var itemPosition = index + 1; - var requestMoreData = - itemPosition % ItemRequestThreshold == 0 && itemPosition != 0; - var pageToRequest = itemPosition ~/ ItemRequestThreshold; - - if (requestMoreData && pageToRequest > _currentPage) { - print('handleItemCreated | pageToRequest: $pageToRequest'); - _currentPage = pageToRequest; - _showLoadingIndicator(); - - await Future.delayed(Duration(seconds: 5)); - var newFetchedItems = List.generate( - 15, (index) => 'Title page:$_currentPage item: $index'); - _items.addAll(newFetchedItems); - - _removeLoadingIndicator(); - } - } - - void _showLoadingIndicator() { - _items.add(LoadingIndicatorTitle); - notifyListeners(); - } - - void _removeLoadingIndicator() { - _items.remove(LoadingIndicatorTitle); - notifyListeners(); - } -} diff --git a/028-continuous-scroll/02-final/lib/views/home_view.dart b/028-continuous-scroll/02-final/lib/views/home_view.dart deleted file mode 100644 index 4933f723..00000000 --- a/028-continuous-scroll/02-final/lib/views/home_view.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:continuous_scroll/viewmodels/home_viewmodel.dart'; -import 'package:continuous_scroll/widgets/creation_aware_list_item.dart'; -import 'package:continuous_scroll/widgets/list_item.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:provider/provider.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: ChangeNotifierProvider( - create: (context) => HomeViewModel(), - child: Consumer( - builder: (context, model, child) => ListView.builder( - itemCount: model.items.length, - itemBuilder: (context, index) => CreationAwareListItem( - itemCreated: () { - SchedulerBinding.instance.addPostFrameCallback( - (duration) => model.handleItemCreated(index)); - }, - child: ListItem( - title: model.items[index], - ), - ), - ), - ), - ), - ); - } -} diff --git a/028-continuous-scroll/02-final/lib/widgets/creation_aware_list_item.dart b/028-continuous-scroll/02-final/lib/widgets/creation_aware_list_item.dart deleted file mode 100644 index 07739f9c..00000000 --- a/028-continuous-scroll/02-final/lib/widgets/creation_aware_list_item.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -class CreationAwareListItem extends StatefulWidget { - final Function itemCreated; - final Widget child; - const CreationAwareListItem({ - Key key, - this.itemCreated, - this.child, - }) : super(key: key); - - @override - _CreationAwareListItemState createState() => _CreationAwareListItemState(); -} - -class _CreationAwareListItemState extends State { - @override - void initState() { - super.initState(); - if (widget.itemCreated != null) { - widget.itemCreated(); - } - } - - @override - Widget build(BuildContext context) { - return widget.child; - } -} diff --git a/028-continuous-scroll/02-final/lib/widgets/list_item.dart b/028-continuous-scroll/02-final/lib/widgets/list_item.dart deleted file mode 100644 index 4201a3f4..00000000 --- a/028-continuous-scroll/02-final/lib/widgets/list_item.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:continuous_scroll/constants/ui_constants.dart'; -import 'package:flutter/material.dart'; - -class ListItem extends StatelessWidget { - final String title; - const ListItem({Key key, this.title}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 15), - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.grey[400], - ), - ], - borderRadius: BorderRadius.circular(5)), - child: title == LoadingIndicatorTitle - ? CircularProgressIndicator() - : Text(title), - alignment: Alignment.center, - ); - } -} diff --git a/028-continuous-scroll/02-final/pubspec.lock b/028-continuous-scroll/02-final/pubspec.lock deleted file mode 100644 index fda2d6aa..00000000 --- a/028-continuous-scroll/02-final/pubspec.lock +++ /dev/null @@ -1,161 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/028-continuous-scroll/02-final/pubspec.yaml b/028-continuous-scroll/02-final/pubspec.yaml deleted file mode 100644 index 12c70026..00000000 --- a/028-continuous-scroll/02-final/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: continuous_scroll -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/028-continuous-scroll/02-final/test/widget_test.dart b/028-continuous-scroll/02-final/test/widget_test.dart deleted file mode 100644 index 65f38bb8..00000000 --- a/028-continuous-scroll/02-final/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:continuous_scroll/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/029-responsive-architecture-additions/.flutter-plugins-dependencies b/029-responsive-architecture-additions/.flutter-plugins-dependencies deleted file mode 100644 index e087fcbf..00000000 --- a/029-responsive-architecture-additions/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:56.606961","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/029-responsive-architecture-additions/.gitignore b/029-responsive-architecture-additions/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/029-responsive-architecture-additions/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/029-responsive-architecture-additions/.metadata b/029-responsive-architecture-additions/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/029-responsive-architecture-additions/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/029-responsive-architecture-additions/README.md b/029-responsive-architecture-additions/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/029-responsive-architecture-additions/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/029-responsive-architecture-additions/lib/enums/device_screen_type.dart b/029-responsive-architecture-additions/lib/enums/device_screen_type.dart deleted file mode 100644 index ad5aed51..00000000 --- a/029-responsive-architecture-additions/lib/enums/device_screen_type.dart +++ /dev/null @@ -1 +0,0 @@ -enum DeviceScreenType { Mobile, Tablet, Desktop } diff --git a/029-responsive-architecture-additions/lib/main.dart b/029-responsive-architecture-additions/lib/main.dart deleted file mode 100644 index c05392ec..00000000 --- a/029-responsive-architecture-additions/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/views/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/029-responsive-architecture-additions/lib/ui/base_widget.dart b/029-responsive-architecture-additions/lib/ui/base_widget.dart deleted file mode 100644 index d9b1ce71..00000000 --- a/029-responsive-architecture-additions/lib/ui/base_widget.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class BaseWidget extends StatelessWidget { - final Widget Function( - BuildContext context, SizingInformation sizingInformation) builder; - const BaseWidget({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - var mediaQuery = MediaQuery.of(context); - - return LayoutBuilder(builder: (context, boxConstraints) { - var sizingInformation = SizingInformation( - orientation: mediaQuery.orientation, - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/029-responsive-architecture-additions/lib/ui/sizing_information.dart b/029-responsive-architecture-additions/lib/ui/sizing_information.dart deleted file mode 100644 index e9dff561..00000000 --- a/029-responsive-architecture-additions/lib/ui/sizing_information.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final Orientation orientation; - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.orientation, - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'Orientation:$orientation DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/029-responsive-architecture-additions/lib/ui/views/home_view.dart b/029-responsive-architecture-additions/lib/ui/views/home_view.dart deleted file mode 100644 index 2739046b..00000000 --- a/029-responsive-architecture-additions/lib/ui/views/home_view.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/base_widget.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return BaseWidget( - builder: (context, sizingInformation) { - return Scaffold( - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Container( - height: 150, - margin: const EdgeInsets.all(50), - color: Colors.blue, - child: BaseWidget(builder: (context, sizingInfo) => Text(sizingInfo.toString()),), - ), - Text(sizingInformation.toString()), - ], - ), - ), - ); - }, - ); - } -} diff --git a/029-responsive-architecture-additions/lib/utils/ui_utils.dart b/029-responsive-architecture-additions/lib/utils/ui_utils.dart deleted file mode 100644 index ec70524a..00000000 --- a/029-responsive-architecture-additions/lib/utils/ui_utils.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - var orientation = mediaQuery.orientation; - - // Fixed Device width (changes with orientation) - double deviceWidth = 0; - - if (orientation == Orientation.landscape) { - deviceWidth = mediaQuery.size.height; - } else { - deviceWidth = mediaQuery.size.width; - } - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/029-responsive-architecture-additions/pubspec.lock b/029-responsive-architecture-additions/pubspec.lock deleted file mode 100644 index 9fba4513..00000000 --- a/029-responsive-architecture-additions/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/029-responsive-architecture-additions/pubspec.yaml b/029-responsive-architecture-additions/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/029-responsive-architecture-additions/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/029-responsive-architecture-additions/test/widget_test.dart b/029-responsive-architecture-additions/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/029-responsive-architecture-additions/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/030-responsive-layout-building/00-final-multiple-files/.flutter-plugins-dependencies b/030-responsive-layout-building/00-final-multiple-files/.flutter-plugins-dependencies deleted file mode 100644 index 1c930a59..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:27.608577","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/030-responsive-layout-building/00-final-multiple-files/.gitignore b/030-responsive-layout-building/00-final-multiple-files/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/030-responsive-layout-building/00-final-multiple-files/.metadata b/030-responsive-layout-building/00-final-multiple-files/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/030-responsive-layout-building/00-final-multiple-files/README.md b/030-responsive-layout-building/00-final-multiple-files/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/enums/device_screen_type.dart b/030-responsive-layout-building/00-final-multiple-files/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/main.dart b/030-responsive-layout-building/00-final-multiple-files/lib/main.dart deleted file mode 100644 index 602c3954..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/orientation_layout.dart b/030-responsive-layout-building/00-final-multiple-files/lib/responsive/orientation_layout.dart deleted file mode 100644 index 266fd9c7..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/orientation_layout.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class OrientationLayout extends StatelessWidget { - final Widget landscape; - final Widget portrait; - const OrientationLayout({ - Key key, - this.landscape, - this.portrait, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var orientation = MediaQuery.of(context).orientation; - if (orientation == Orientation.landscape) { - return landscape ?? portrait; - } - - return portrait; - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/responsive_builder.dart b/030-responsive-layout-building/00-final-multiple-files/lib/responsive/responsive_builder.dart deleted file mode 100644 index 4fac7cf2..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/responsive_builder.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, - SizingInformation sizingInformation, - ) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/screen_type_layout.dart b/030-responsive-layout-building/00-final-multiple-files/lib/responsive/screen_type_layout.dart deleted file mode 100644 index 0bf4a92a..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/screen_type_layout.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/responsive/responsive_builder.dart'; - -class ScreenTypeLayout extends StatelessWidget { - final Widget mobile; - final Widget tablet; - final Widget desktop; - const ScreenTypeLayout({ - Key key, - this.mobile, - this.tablet, - this.desktop, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - if (sizingInformation.deviceScreenType == DeviceScreenType.Tablet) { - if (tablet != null) { - return tablet; - } - } - - if (sizingInformation.deviceScreenType == DeviceScreenType.Desktop) { - if (desktop != null) { - return desktop; - } - } - - return mobile; - }, - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/sizing_information.dart b/030-responsive-layout-building/00-final-multiple-files/lib/responsive/sizing_information.dart deleted file mode 100644 index a2c84863..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/responsive/sizing_information.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/utils/ui_utils.dart b/030-responsive-layout-building/00-final-multiple-files/lib/utils/ui_utils.dart deleted file mode 100644 index 7632593b..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/utils/ui_utils.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - double deviceWidth = mediaQuery.size.shortestSide; - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view.dart b/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view.dart deleted file mode 100644 index fa087450..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; - -import 'home_view_mobile.dart'; -import 'home_view_tablet.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: OrientationLayout( - portrait: HomeMobilePortrait(), - landscape: HomeMobileLandscape(), - ), - tablet: HomeViewTablet(), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view_mobile.dart b/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view_mobile.dart deleted file mode 100644 index 6ee71815..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view_mobile.dart +++ /dev/null @@ -1,44 +0,0 @@ -/// Contains the widgets that will be used for Mobile layout of home, -/// portrait and landscape - -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer.dart'; - -class HomeMobilePortrait extends StatelessWidget { - final GlobalKey _scaffoldKey = GlobalKey(); - HomeMobilePortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - drawer: AppDrawer(), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16), - child: IconButton( - icon: Icon(Icons.menu, size: 30), - onPressed: () { - _scaffoldKey.currentState.openDrawer(); - }, - ), - ) - ], - ), - ); - } -} - -class HomeMobileLandscape extends StatelessWidget { - const HomeMobileLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row(children: [ - AppDrawer() - ],), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view_tablet.dart b/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view_tablet.dart deleted file mode 100644 index 0b40fb2e..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/views/home/home_view_tablet.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer.dart'; - -class HomeViewTablet extends StatelessWidget { - const HomeViewTablet({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var children = [ - Expanded( - child: Container(), - ), - AppDrawer() - ]; - var orientation = MediaQuery.of(context).orientation; - return Scaffold( - body: orientation == Orientation.portrait - ? Column(children: children) - : Row(children: children.reversed.toList()), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer.dart b/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer.dart deleted file mode 100644 index fc7c602b..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer_mobile.dart'; -import 'package:responsive_architecture/widgets/drawer_option/drawer_option.dart'; - -import 'app_drawer_tablet.dart'; - -class AppDrawer extends StatelessWidget { - const AppDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: AppDrawerMobile(), - tablet: OrientationLayout( - portrait: AppDrawerTabletPortrait(), - landscape: AppDrawerTabletLandscape(), - ), - ); - } - - static List getDrawerOptions() { - return [ - DrawerOption( - title: 'Images', - iconData: Icons.image, - ), - DrawerOption( - title: 'Reports', - iconData: Icons.photo_filter, - ), - DrawerOption( - title: 'Incidents', - iconData: Icons.message, - ), - DrawerOption( - title: 'Settings', - iconData: Icons.settings, - ), - ]; - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer_mobile.dart b/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer_mobile.dart deleted file mode 100644 index 8ef7d60a..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app_drawer.dart'; - -class AppDrawerMobile extends StatelessWidget { - const AppDrawerMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var orientation = MediaQuery.of(context).orientation; - return Container( - width: orientation == Orientation.portrait ? 250 : 100, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Column(children: AppDrawer.getDrawerOptions(),), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer_tablet.dart b/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer_tablet.dart deleted file mode 100644 index aab8d9f7..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/app_drawer/app_drawer_tablet.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app_drawer.dart'; - -class AppDrawerTabletPortrait extends StatelessWidget { - const AppDrawerTabletPortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 130, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Row( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} - -class AppDrawerTabletLandscape extends StatelessWidget { - const AppDrawerTabletLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 250, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Column( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option.dart b/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option.dart deleted file mode 100644 index e373fef0..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; - -import 'drawer_option_mobile.dart'; -import 'drawer_option_tablet.dart'; - -class DrawerOption extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOption({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: OrientationLayout( - landscape: DrawerOptionMobileLandscape( - iconData: iconData, - ), - portrait: DrawerOptionMobilePortrait( - title: title, - iconData: iconData, - ), - ), - tablet: OrientationLayout( - portrait: DrawerOptionTabletPortrait( - iconData: iconData, - title: title, - ), - landscape: DrawerOptionMobilePortrait( - iconData: iconData, - title: title, - ), - ), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option_mobile.dart b/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option_mobile.dart deleted file mode 100644 index f57c6abe..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option_mobile.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; - -class DrawerOptionMobilePortrait extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOptionMobilePortrait({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.only(left: 25), - height: 80, - child: Row( - children: [ - Icon( - iconData, - size: 25, - ), - SizedBox( - width: 25, - ), - Text( - title, - style: TextStyle(fontSize: 21), - ) - ], - ), - ); - } -} - -class DrawerOptionMobileLandscape extends StatelessWidget { - final IconData iconData; - const DrawerOptionMobileLandscape({Key key, this.iconData}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 70, - alignment: Alignment.center, - child: Icon(iconData), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option_tablet.dart b/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option_tablet.dart deleted file mode 100644 index 73318dfc..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/lib/widgets/drawer_option/drawer_option_tablet.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -class DrawerOptionTabletPortrait extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOptionTabletPortrait({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 152, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - iconData, - size: 45, - ), - Text(title, style: TextStyle(fontSize: 20)), - ], - ), - ); - } -} diff --git a/030-responsive-layout-building/00-final-multiple-files/pubspec.lock b/030-responsive-layout-building/00-final-multiple-files/pubspec.lock deleted file mode 100644 index 6ad2a21d..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/030-responsive-layout-building/00-final-multiple-files/pubspec.yaml b/030-responsive-layout-building/00-final-multiple-files/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/030-responsive-layout-building/00-final-multiple-files/test/widget_test.dart b/030-responsive-layout-building/00-final-multiple-files/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/030-responsive-layout-building/00-final-multiple-files/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/.flutter-plugins-dependencies b/030-responsive-layout-building/00-final-tutorial-single-file/.flutter-plugins-dependencies deleted file mode 100644 index 1d35c874..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:26.192944","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/.gitignore b/030-responsive-layout-building/00-final-tutorial-single-file/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/.metadata b/030-responsive-layout-building/00-final-tutorial-single-file/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/README.md b/030-responsive-layout-building/00-final-tutorial-single-file/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/enums/device_screen_type.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/main.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/main.dart deleted file mode 100644 index 602c3954..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/orientation_layout.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/orientation_layout.dart deleted file mode 100644 index 0f2bd04f..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/orientation_layout.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class OrientationLayout extends StatelessWidget { - final Widget landscape; - final Widget portrait; - OrientationLayout({ - Key key, - this.landscape, - @required this.portrait, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var orientation = MediaQuery.of(context).orientation; - if (orientation == Orientation.landscape) { - return landscape ?? portrait; - } - - return portrait; - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/responsive_builder.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/responsive_builder.dart deleted file mode 100644 index 4fac7cf2..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/responsive_builder.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, - SizingInformation sizingInformation, - ) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/screen_type_layout.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/screen_type_layout.dart deleted file mode 100644 index f676974b..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/screen_type_layout.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/responsive/responsive_builder.dart'; - -class ScreenTypeLayout extends StatelessWidget { - // Mobile will be returned by default - final Widget mobile; - final Widget tablet; - final Widget desktop; - - const ScreenTypeLayout( - {Key key, @required this.mobile, this.tablet, this.desktop}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder(builder: (context, sizingInformation) { - // If sizing indicates Tablet and we have a tablet widget then return - if (sizingInformation.deviceScreenType == DeviceScreenType.Tablet) { - if (tablet != null) { - return tablet; - } - } - - // If sizing indicates desktop and we have a desktop widget then return - if (sizingInformation.deviceScreenType == DeviceScreenType.Desktop) { - if (desktop != null) { - return desktop; - } - } - - // Return mobile layout if nothing else is supplied - return mobile; - }); - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/sizing_information.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/sizing_information.dart deleted file mode 100644 index a2c84863..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/responsive/sizing_information.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/utils/ui_utils.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/utils/ui_utils.dart deleted file mode 100644 index 7632593b..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/utils/ui_utils.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - double deviceWidth = mediaQuery.size.shortestSide; - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/views/home/home_view.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/views/home/home_view.dart deleted file mode 100644 index 140621dc..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/views/home/home_view.dart +++ /dev/null @@ -1,86 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; -import 'package:responsive_architecture/widgets/app_drawer.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: OrientationLayout( - portrait: _MobilePortrait(), - landscape: const _MobileLandscape(), - ), - tablet: const _HomeTablet(), - ); - } -} - -class _MobilePortrait extends StatelessWidget { - final GlobalKey _scaffoldKey = GlobalKey(); - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - drawer: AppDrawer(), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: IconButton( - icon: Icon( - Icons.menu, - size: 30, - ), - onPressed: () { - _scaffoldKey.currentState.openDrawer(); - }, - ), - ) - ], - ), - ); - } -} - -class _MobileLandscape extends StatelessWidget { - const _MobileLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row( - children: [AppDrawer()], - ), - ); - } -} - -class _HomeTablet extends StatelessWidget { - const _HomeTablet({ - Key key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var children = [ - Expanded( - child: Container(), - ), - AppDrawer() - ]; - var orientation = MediaQuery.of(context).orientation; - return Scaffold( - body: orientation == Orientation.portrait - ? Column( - children: children, - ) - : Row( - children: children.reversed.toList(), - ), - ); - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/widgets/app_drawer.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/widgets/app_drawer.dart deleted file mode 100644 index cc69ed17..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/widgets/app_drawer.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; - -import 'drawer_option.dart'; - -class AppDrawer extends StatelessWidget { - const AppDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: _MobileLayout(), - tablet: OrientationLayout( - portrait: const _TabletPortrait(), - landscape: const _TabletLandscape(), - ), - ); - } - - static List getDrawerOptions() { - return [ - DrawerOption( - title: 'Images', - iconData: Icons.image, - ), - DrawerOption( - title: 'Reports', - iconData: Icons.photo_filter, - ), - DrawerOption( - title: 'Incidents', - iconData: Icons.message, - ), - DrawerOption( - title: 'Settings', - iconData: Icons.settings, - ), - ]; - } -} - -class _MobileLayout extends StatelessWidget { - const _MobileLayout({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var orientation = MediaQuery.of(context).orientation; - return Container( - width: orientation == Orientation.portrait ? 250 : 100, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ], - ), - child: Column( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} - -class _TabletPortrait extends StatelessWidget { - const _TabletPortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 130, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - child: Row( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} - -class _TabletLandscape extends StatelessWidget { - const _TabletLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 250, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - child: Column( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/lib/widgets/drawer_option.dart b/030-responsive-layout-building/00-final-tutorial-single-file/lib/widgets/drawer_option.dart deleted file mode 100644 index 1114df74..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/lib/widgets/drawer_option.dart +++ /dev/null @@ -1,116 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; - -class DrawerOption extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOption({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: OrientationLayout( - portrait: _MobilePortrait( - title: title, - iconData: iconData, - ), - landscape: _MobileLandscape( - iconData: iconData, - ), - ), - tablet: OrientationLayout( - portrait: _TabletPortrait( - title: title, - iconData: iconData, - ), - landscape: _MobilePortrait( - title: title, - iconData: iconData, - ), - ), - ); - } -} - -class _MobilePortrait extends StatelessWidget { - final String title; - final IconData iconData; - const _MobilePortrait({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.only(left: 25), - height: 80, - child: Row( - children: [ - Icon( - iconData, - size: 25, - ), - SizedBox( - width: 25, - ), - Text( - title, - style: TextStyle(fontSize: 21), - ) - ], - ), - ); - } -} - -class _MobileLandscape extends StatelessWidget { - final IconData iconData; - const _MobileLandscape({Key key, this.iconData}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 70, - alignment: Alignment.center, - child: Icon( - iconData, - size: 30, - ), - ); - } -} - -class _TabletPortrait extends StatelessWidget { - final String title; - final IconData iconData; - const _TabletPortrait({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 152, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - iconData, - size: 45, - ), - Text(title, style: TextStyle(fontSize: 20)), - ], - ), - ); - } -} diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/pubspec.lock b/030-responsive-layout-building/00-final-tutorial-single-file/pubspec.lock deleted file mode 100644 index 9fba4513..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/pubspec.yaml b/030-responsive-layout-building/00-final-tutorial-single-file/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/030-responsive-layout-building/00-final-tutorial-single-file/test/widget_test.dart b/030-responsive-layout-building/00-final-tutorial-single-file/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/030-responsive-layout-building/00-final-tutorial-single-file/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/030-responsive-layout-building/00-starting-tutorial/.flutter-plugins-dependencies b/030-responsive-layout-building/00-starting-tutorial/.flutter-plugins-dependencies deleted file mode 100644 index be76547d..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:24.731131","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/030-responsive-layout-building/00-starting-tutorial/.gitignore b/030-responsive-layout-building/00-starting-tutorial/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/030-responsive-layout-building/00-starting-tutorial/.metadata b/030-responsive-layout-building/00-starting-tutorial/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/030-responsive-layout-building/00-starting-tutorial/README.md b/030-responsive-layout-building/00-starting-tutorial/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/030-responsive-layout-building/00-starting-tutorial/lib/enums/device_screen_type.dart b/030-responsive-layout-building/00-starting-tutorial/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/030-responsive-layout-building/00-starting-tutorial/lib/main.dart b/030-responsive-layout-building/00-starting-tutorial/lib/main.dart deleted file mode 100644 index 602c3954..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/030-responsive-layout-building/00-starting-tutorial/lib/responsive/responsive_builder.dart b/030-responsive-layout-building/00-starting-tutorial/lib/responsive/responsive_builder.dart deleted file mode 100644 index 4fac7cf2..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/lib/responsive/responsive_builder.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, - SizingInformation sizingInformation, - ) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/030-responsive-layout-building/00-starting-tutorial/lib/responsive/sizing_information.dart b/030-responsive-layout-building/00-starting-tutorial/lib/responsive/sizing_information.dart deleted file mode 100644 index a2c84863..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/lib/responsive/sizing_information.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/030-responsive-layout-building/00-starting-tutorial/lib/utils/ui_utils.dart b/030-responsive-layout-building/00-starting-tutorial/lib/utils/ui_utils.dart deleted file mode 100644 index 7632593b..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/lib/utils/ui_utils.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - double deviceWidth = mediaQuery.size.shortestSide; - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/030-responsive-layout-building/00-starting-tutorial/lib/views/home/home_view.dart b/030-responsive-layout-building/00-starting-tutorial/lib/views/home/home_view.dart deleted file mode 100644 index a840a71a..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/lib/views/home/home_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.white, - ); - } -} diff --git a/030-responsive-layout-building/00-starting-tutorial/pubspec.lock b/030-responsive-layout-building/00-starting-tutorial/pubspec.lock deleted file mode 100644 index 9fba4513..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/030-responsive-layout-building/00-starting-tutorial/pubspec.yaml b/030-responsive-layout-building/00-starting-tutorial/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/030-responsive-layout-building/00-starting-tutorial/test/widget_test.dart b/030-responsive-layout-building/00-starting-tutorial/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/030-responsive-layout-building/00-starting-tutorial/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/030-responsive-layout-building/01-file-per-layout/.flutter-plugins-dependencies b/030-responsive-layout-building/01-file-per-layout/.flutter-plugins-dependencies deleted file mode 100644 index 4b838c31..00000000 --- a/030-responsive-layout-building/01-file-per-layout/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:30.516844","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/030-responsive-layout-building/01-file-per-layout/.gitignore b/030-responsive-layout-building/01-file-per-layout/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/030-responsive-layout-building/01-file-per-layout/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/030-responsive-layout-building/01-file-per-layout/.metadata b/030-responsive-layout-building/01-file-per-layout/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/030-responsive-layout-building/01-file-per-layout/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/030-responsive-layout-building/01-file-per-layout/README.md b/030-responsive-layout-building/01-file-per-layout/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/030-responsive-layout-building/01-file-per-layout/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/030-responsive-layout-building/01-file-per-layout/lib/enums/device_screen_type.dart b/030-responsive-layout-building/01-file-per-layout/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/030-responsive-layout-building/01-file-per-layout/lib/main.dart b/030-responsive-layout-building/01-file-per-layout/lib/main.dart deleted file mode 100644 index 1ffcd5a3..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/responsive_builder.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/responsive_builder.dart deleted file mode 100644 index 3fc4ca03..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/responsive_builder.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, SizingInformation sizingInformation) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - orientation: mediaQuery.orientation, - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/sizing_information.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/sizing_information.dart deleted file mode 100644 index e9dff561..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/sizing_information.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final Orientation orientation; - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.orientation, - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'Orientation:$orientation DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer.dart deleted file mode 100644 index 06495e3a..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/ui/responsive_builder.dart'; -import 'package:responsive_architecture/ui/views/home/drawer/app_drawer_mobile.dart'; - -import 'app_drawer_tablet.dart'; - -class AppDrawer extends StatelessWidget { - const AppDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder(builder: (context, sizingInformation) { - if (sizingInformation.deviceScreenType == DeviceScreenType.Mobile) { - return AppDrawerMobile( - sizingInformation: sizingInformation, - ); - } - - return AppDrawerTablet( - sizingInformation: sizingInformation, - ); - }); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer_mobile.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer_mobile.dart deleted file mode 100644 index 413babe2..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer_mobile.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/sizing_information.dart'; - -class AppDrawerMobile extends StatelessWidget { - final SizingInformation sizingInformation; - const AppDrawerMobile({Key key, this.sizingInformation}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: sizingInformation.orientation == Orientation.landscape ? 100 : 250, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - ); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer_tablet.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer_tablet.dart deleted file mode 100644 index 5ffc8e20..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/drawer/app_drawer_tablet.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/sizing_information.dart'; - -class AppDrawerTablet extends StatelessWidget { - final SizingInformation sizingInformation; - const AppDrawerTablet({ - Key key, - this.sizingInformation, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if (sizingInformation.orientation == Orientation.portrait) { - return _AppDrawerPortrait(); - } - - return _AppDrawerLandscape(); - } -} - -class _AppDrawerPortrait extends StatelessWidget { - const _AppDrawerPortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 130, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ]), - ); - } -} - -class _AppDrawerLandscape extends StatelessWidget { - const _AppDrawerLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 350, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ]), - ); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_mobile.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_mobile.dart deleted file mode 100644 index fd5bcbbf..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_mobile.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/views/home/drawer/app_drawer.dart'; - -import '../../sizing_information.dart'; - -class HomeMobile extends StatelessWidget { - final SizingInformation sizingInformation; - HomeMobile({ - Key key, - @required this.sizingInformation, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - if (sizingInformation.orientation == Orientation.portrait) { - return _HomePortrait(); - } - - return _HomeLandscape(); - } -} - -class _HomePortrait extends StatelessWidget { - final GlobalKey _scaffoldKey = GlobalKey(); - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - drawer: AppDrawer(), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: IconButton( - icon: Icon( - Icons.menu, - size: 30, - ), - onPressed: () { - _scaffoldKey.currentState.openDrawer(); - }, - ), - ) - ], - ), - ); - } -} - -class _HomeLandscape extends StatelessWidget { - const _HomeLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row( - children: [AppDrawer()], - ), - ); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_tablet.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_tablet.dart deleted file mode 100644 index 28f45f3e..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_tablet.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/sizing_information.dart'; -import 'package:responsive_architecture/ui/views/home/drawer/app_drawer.dart'; - -class HomeTablet extends StatelessWidget { - final SizingInformation sizingInformation; - HomeTablet({ - Key key, - this.sizingInformation, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var children = [ - Expanded( - child: Container(), - ), - AppDrawer() - ]; - return Scaffold( - body: sizingInformation.orientation == Orientation.portrait - ? Column( - children: children, - ) - : Row( - children: children.reversed.toList(), - ), - ); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_view.dart b/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_view.dart deleted file mode 100644 index 687a2546..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/ui/views/home/home_view.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/ui/responsive_builder.dart'; -import 'package:responsive_architecture/ui/views/home/home_mobile.dart'; -import 'package:responsive_architecture/ui/views/home/home_tablet.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - if (sizingInformation.deviceScreenType == DeviceScreenType.Mobile) { - return HomeMobile( - sizingInformation: sizingInformation, - ); - } - - return HomeTablet( - sizingInformation: sizingInformation, - ); - }, - ); - } -} diff --git a/030-responsive-layout-building/01-file-per-layout/lib/utils/ui_utils.dart b/030-responsive-layout-building/01-file-per-layout/lib/utils/ui_utils.dart deleted file mode 100644 index ec70524a..00000000 --- a/030-responsive-layout-building/01-file-per-layout/lib/utils/ui_utils.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - var orientation = mediaQuery.orientation; - - // Fixed Device width (changes with orientation) - double deviceWidth = 0; - - if (orientation == Orientation.landscape) { - deviceWidth = mediaQuery.size.height; - } else { - deviceWidth = mediaQuery.size.width; - } - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/030-responsive-layout-building/01-file-per-layout/pubspec.lock b/030-responsive-layout-building/01-file-per-layout/pubspec.lock deleted file mode 100644 index 9fba4513..00000000 --- a/030-responsive-layout-building/01-file-per-layout/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/030-responsive-layout-building/01-file-per-layout/pubspec.yaml b/030-responsive-layout-building/01-file-per-layout/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/030-responsive-layout-building/01-file-per-layout/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/030-responsive-layout-building/01-file-per-layout/test/widget_test.dart b/030-responsive-layout-building/01-file-per-layout/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/030-responsive-layout-building/01-file-per-layout/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/.flutter-plugins-dependencies b/030-responsive-layout-building/02-screentype-orientation-builder/.flutter-plugins-dependencies deleted file mode 100644 index 825e08e8..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:31.878565","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/.gitignore b/030-responsive-layout-building/02-screentype-orientation-builder/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/.metadata b/030-responsive-layout-building/02-screentype-orientation-builder/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/README.md b/030-responsive-layout-building/02-screentype-orientation-builder/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/enums/device_screen_type.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/main.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/main.dart deleted file mode 100644 index 1ffcd5a3..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/responsive_builder.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/responsive_builder.dart deleted file mode 100644 index ca960cb0..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/responsive_builder.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, - SizingInformation sizingInformation, - ) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/screentype_builder.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/screentype_builder.dart deleted file mode 100644 index a0493843..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/screentype_builder.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/ui/responsive_builder.dart'; - -class ScreenTypeBuilder extends StatelessWidget { - // Mobile will be returned by default - final Widget mobile; - final Widget tablet; - final Widget desktop; - - const ScreenTypeBuilder( - {Key key, @required this.mobile, this.tablet, this.desktop}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder(builder: (context, sizingInformation) { - // If sizing indicates Tablet and we have a tablet widget then return - if (sizingInformation.deviceScreenType == DeviceScreenType.Tablet) { - if (tablet != null) { - return tablet; - } - } - - // If sizing indicates desktop and we have a desktop widget then return - if (sizingInformation.deviceScreenType == DeviceScreenType.Desktop) { - if (desktop != null) { - return desktop; - } - } - - // Return mobile layout if nothing else is supplied - return mobile; - }); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/sizing_information.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/sizing_information.dart deleted file mode 100644 index a2c84863..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/sizing_information.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_mobile.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_mobile.dart deleted file mode 100644 index 5b8406e2..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_mobile.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/widgets/drawer/app_drawer.dart'; - -class HomeMobile extends StatelessWidget { - @override - Widget build(BuildContext context) { - return OrientationBuilder( - builder: (context, orientation) { - if (orientation == Orientation.portrait) { - return _HomePortrait(); - } - - return _HomeLandscape(); - }, - ); - } -} - -class _HomePortrait extends StatelessWidget { - final GlobalKey _scaffoldKey = GlobalKey(); - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - drawer: AppDrawer(), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: IconButton( - icon: Icon( - Icons.menu, - size: 30, - ), - onPressed: () { - _scaffoldKey.currentState.openDrawer(); - }, - ), - ) - ], - ), - ); - } -} - -class _HomeLandscape extends StatelessWidget { - const _HomeLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row( - children: [AppDrawer()], - ), - ); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_tablet.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_tablet.dart deleted file mode 100644 index 04cdb816..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_tablet.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/widgets/drawer/app_drawer.dart'; - -class HomeTablet extends StatelessWidget { - HomeTablet({ - Key key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var children = [ - Expanded( - child: Container(), - ), - AppDrawer() - ]; - return OrientationBuilder( - builder: (context, orientation) => Scaffold( - body: orientation == Orientation.portrait - ? Column( - children: children, - ) - : Row( - children: children.reversed.toList(), - ), - ), - ); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_view.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_view.dart deleted file mode 100644 index 6026f6fb..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/views/home/home_view.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/screentype_builder.dart'; -import 'package:responsive_architecture/ui/views/home/home_mobile.dart'; -import 'package:responsive_architecture/ui/views/home/home_tablet.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeBuilder( - mobile: HomeMobile(), - tablet: HomeTablet(), - ); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer.dart deleted file mode 100644 index 52bbe3dc..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/ui/screentype_builder.dart'; - -import 'app_drawer_mobile.dart'; -import 'app_drawer_tablet.dart'; - -class AppDrawer extends StatelessWidget { - const AppDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeBuilder( - mobile: AppDrawerMobile(), - tablet: AppDrawerTablet(), - ); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer_mobile.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer_mobile.dart deleted file mode 100644 index 7a014258..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer_mobile.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/material.dart'; - -class AppDrawerMobile extends StatelessWidget { - const AppDrawerMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return OrientationBuilder( - builder: (context, orientation) => Container( - width: orientation == Orientation.landscape ? 100 : 250, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - ), - ); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer_tablet.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer_tablet.dart deleted file mode 100644 index fedeec8a..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/ui/widgets/drawer/app_drawer_tablet.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:flutter/material.dart'; - -class AppDrawerTablet extends StatelessWidget { - const AppDrawerTablet({ - Key key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return OrientationBuilder(builder: (context, orientation) { - if (orientation == Orientation.portrait) { - return _AppDrawerPortrait(); - } - - return _AppDrawerLandscape(); - }); - } -} - -class _AppDrawerPortrait extends StatelessWidget { - const _AppDrawerPortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 130, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - ); - } -} - -class _AppDrawerLandscape extends StatelessWidget { - const _AppDrawerLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 250, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - ); - } -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/lib/utils/ui_utils.dart b/030-responsive-layout-building/02-screentype-orientation-builder/lib/utils/ui_utils.dart deleted file mode 100644 index 7632593b..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/lib/utils/ui_utils.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - double deviceWidth = mediaQuery.size.shortestSide; - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/pubspec.lock b/030-responsive-layout-building/02-screentype-orientation-builder/pubspec.lock deleted file mode 100644 index 9fba4513..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/pubspec.yaml b/030-responsive-layout-building/02-screentype-orientation-builder/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/030-responsive-layout-building/02-screentype-orientation-builder/test/widget_test.dart b/030-responsive-layout-building/02-screentype-orientation-builder/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/030-responsive-layout-building/02-screentype-orientation-builder/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/030-responsive-layout-building/03-one-file-layouts/.flutter-plugins-dependencies b/030-responsive-layout-building/03-one-file-layouts/.flutter-plugins-dependencies deleted file mode 100644 index b4eaf8dc..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:29.010042","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/030-responsive-layout-building/03-one-file-layouts/.gitignore b/030-responsive-layout-building/03-one-file-layouts/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/030-responsive-layout-building/03-one-file-layouts/.metadata b/030-responsive-layout-building/03-one-file-layouts/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/030-responsive-layout-building/03-one-file-layouts/README.md b/030-responsive-layout-building/03-one-file-layouts/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/enums/device_screen_type.dart b/030-responsive-layout-building/03-one-file-layouts/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/main.dart b/030-responsive-layout-building/03-one-file-layouts/lib/main.dart deleted file mode 100644 index 602c3954..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/responsive_builder.dart b/030-responsive-layout-building/03-one-file-layouts/lib/responsive/responsive_builder.dart deleted file mode 100644 index 4fac7cf2..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/responsive_builder.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, - SizingInformation sizingInformation, - ) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/responsive_orientation_builder.dart b/030-responsive-layout-building/03-one-file-layouts/lib/responsive/responsive_orientation_builder.dart deleted file mode 100644 index 8ea3ba25..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/responsive_orientation_builder.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; - -class ResponsiveOrientationBuilder extends StatelessWidget { - final Widget landscape; - final Widget portrait; - const ResponsiveOrientationBuilder({ - Key key, - this.landscape, - @required this.portrait, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return OrientationBuilder( - builder: (context, orientation) { - if (orientation == Orientation.landscape) { - return landscape ?? portrait; - } - - return portrait; - }, - ); - } -} diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/screentype_builder.dart b/030-responsive-layout-building/03-one-file-layouts/lib/responsive/screentype_builder.dart deleted file mode 100644 index b8017d90..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/screentype_builder.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/responsive/responsive_builder.dart'; - -class ScreenTypeBuilder extends StatelessWidget { - // Mobile will be returned by default - final Widget mobile; - final Widget tablet; - final Widget desktop; - - const ScreenTypeBuilder( - {Key key, @required this.mobile, this.tablet, this.desktop}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder(builder: (context, sizingInformation) { - // If sizing indicates Tablet and we have a tablet widget then return - if (sizingInformation.deviceScreenType == DeviceScreenType.Tablet) { - if (tablet != null) { - return tablet; - } - } - - // If sizing indicates desktop and we have a desktop widget then return - if (sizingInformation.deviceScreenType == DeviceScreenType.Desktop) { - if (desktop != null) { - return desktop; - } - } - - // Return mobile layout if nothing else is supplied - return mobile; - }); - } -} diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/sizing_information.dart b/030-responsive-layout-building/03-one-file-layouts/lib/responsive/sizing_information.dart deleted file mode 100644 index a2c84863..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/responsive/sizing_information.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/utils/ui_utils.dart b/030-responsive-layout-building/03-one-file-layouts/lib/utils/ui_utils.dart deleted file mode 100644 index 7632593b..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/utils/ui_utils.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - double deviceWidth = mediaQuery.size.shortestSide; - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/views/home/home_view.dart b/030-responsive-layout-building/03-one-file-layouts/lib/views/home/home_view.dart deleted file mode 100644 index b57eef65..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/views/home/home_view.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/responsive_orientation_builder.dart'; -import 'package:responsive_architecture/responsive/screentype_builder.dart'; -import 'package:responsive_architecture/widgets/drawer/app_drawer.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeBuilder( - mobile: ResponsiveOrientationBuilder( - portrait: _HomeMobilePortrait(), - landscape: const _HomeMobileLandscape(), - ), - tablet: const _HomeTablet(), - ); - } -} - -class _HomeMobilePortrait extends StatelessWidget { - final GlobalKey _scaffoldKey = GlobalKey(); - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - drawer: AppDrawer(), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16.0), - child: IconButton( - icon: Icon( - Icons.menu, - size: 30, - ), - onPressed: () { - _scaffoldKey.currentState.openDrawer(); - }, - ), - ) - ], - ), - ); - } -} - -class _HomeMobileLandscape extends StatelessWidget { - const _HomeMobileLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row( - children: [AppDrawer()], - ), - ); - } -} - -class _HomeTablet extends StatelessWidget { - const _HomeTablet({ - Key key, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var children = [ - Expanded( - child: Container(), - ), - AppDrawer() - ]; - return OrientationBuilder( - builder: (context, orientation) => Scaffold( - body: orientation == Orientation.portrait - ? Column( - children: children, - ) - : Row( - children: children.reversed.toList(), - ), - ), - ); - } -} diff --git a/030-responsive-layout-building/03-one-file-layouts/lib/widgets/drawer/app_drawer.dart b/030-responsive-layout-building/03-one-file-layouts/lib/widgets/drawer/app_drawer.dart deleted file mode 100644 index 2c9bb58d..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/lib/widgets/drawer/app_drawer.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/responsive_orientation_builder.dart'; -import 'package:responsive_architecture/responsive/screentype_builder.dart'; - -class AppDrawer extends StatelessWidget { - const AppDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeBuilder( - mobile: _AppDrawerMobile(), - tablet: ResponsiveOrientationBuilder( - portrait: const _AppDrawerTabletPortrait(), - landscape: const _AppDrawerTabletLandscape(), - ), - ); - } -} - -class _AppDrawerMobile extends StatelessWidget { - const _AppDrawerMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return OrientationBuilder( - builder: (context, orientation) => Container( - width: orientation == Orientation.landscape ? 100 : 250, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - ), - ); - } -} - -class _AppDrawerTabletPortrait extends StatelessWidget { - const _AppDrawerTabletPortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 130, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - ); - } -} - -class _AppDrawerTabletLandscape extends StatelessWidget { - const _AppDrawerTabletLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 250, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(blurRadius: 16, color: Colors.black12), - ], - ), - ); - } -} diff --git a/030-responsive-layout-building/03-one-file-layouts/pubspec.lock b/030-responsive-layout-building/03-one-file-layouts/pubspec.lock deleted file mode 100644 index 9fba4513..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/030-responsive-layout-building/03-one-file-layouts/pubspec.yaml b/030-responsive-layout-building/03-one-file-layouts/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/030-responsive-layout-building/03-one-file-layouts/test/widget_test.dart b/030-responsive-layout-building/03-one-file-layouts/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/030-responsive-layout-building/03-one-file-layouts/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/031-responsive-architecture-provider/01-starting/.flutter-plugins-dependencies b/031-responsive-architecture-provider/01-starting/.flutter-plugins-dependencies deleted file mode 100644 index f71dbba2..00000000 --- a/031-responsive-architecture-provider/01-starting/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:11.736514","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/031-responsive-architecture-provider/01-starting/.gitignore b/031-responsive-architecture-provider/01-starting/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/031-responsive-architecture-provider/01-starting/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/031-responsive-architecture-provider/01-starting/.metadata b/031-responsive-architecture-provider/01-starting/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/031-responsive-architecture-provider/01-starting/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/031-responsive-architecture-provider/01-starting/README.md b/031-responsive-architecture-provider/01-starting/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/031-responsive-architecture-provider/01-starting/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/031-responsive-architecture-provider/01-starting/lib/enums/device_screen_type.dart b/031-responsive-architecture-provider/01-starting/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/031-responsive-architecture-provider/01-starting/lib/main.dart b/031-responsive-architecture-provider/01-starting/lib/main.dart deleted file mode 100644 index 602c3954..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/responsive/orientation_layout.dart b/031-responsive-architecture-provider/01-starting/lib/responsive/orientation_layout.dart deleted file mode 100644 index 266fd9c7..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/responsive/orientation_layout.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class OrientationLayout extends StatelessWidget { - final Widget landscape; - final Widget portrait; - const OrientationLayout({ - Key key, - this.landscape, - this.portrait, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - var orientation = MediaQuery.of(context).orientation; - if (orientation == Orientation.landscape) { - return landscape ?? portrait; - } - - return portrait; - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/responsive/responsive_builder.dart b/031-responsive-architecture-provider/01-starting/lib/responsive/responsive_builder.dart deleted file mode 100644 index 4fac7cf2..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/responsive/responsive_builder.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, - SizingInformation sizingInformation, - ) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/responsive/screen_type_layout.dart b/031-responsive-architecture-provider/01-starting/lib/responsive/screen_type_layout.dart deleted file mode 100644 index 0bf4a92a..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/responsive/screen_type_layout.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/responsive/responsive_builder.dart'; - -class ScreenTypeLayout extends StatelessWidget { - final Widget mobile; - final Widget tablet; - final Widget desktop; - const ScreenTypeLayout({ - Key key, - this.mobile, - this.tablet, - this.desktop, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - if (sizingInformation.deviceScreenType == DeviceScreenType.Tablet) { - if (tablet != null) { - return tablet; - } - } - - if (sizingInformation.deviceScreenType == DeviceScreenType.Desktop) { - if (desktop != null) { - return desktop; - } - } - - return mobile; - }, - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/responsive/sizing_information.dart b/031-responsive-architecture-provider/01-starting/lib/responsive/sizing_information.dart deleted file mode 100644 index a2c84863..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/responsive/sizing_information.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/utils/ui_utils.dart b/031-responsive-architecture-provider/01-starting/lib/utils/ui_utils.dart deleted file mode 100644 index 7632593b..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/utils/ui_utils.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - double deviceWidth = mediaQuery.size.shortestSide; - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/031-responsive-architecture-provider/01-starting/lib/views/home/home_view.dart b/031-responsive-architecture-provider/01-starting/lib/views/home/home_view.dart deleted file mode 100644 index fa087450..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/views/home/home_view.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; - -import 'home_view_mobile.dart'; -import 'home_view_tablet.dart'; - -class HomeView extends StatelessWidget { - HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: OrientationLayout( - portrait: HomeMobilePortrait(), - landscape: HomeMobileLandscape(), - ), - tablet: HomeViewTablet(), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/views/home/home_view_mobile.dart b/031-responsive-architecture-provider/01-starting/lib/views/home/home_view_mobile.dart deleted file mode 100644 index 6ee71815..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/views/home/home_view_mobile.dart +++ /dev/null @@ -1,44 +0,0 @@ -/// Contains the widgets that will be used for Mobile layout of home, -/// portrait and landscape - -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer.dart'; - -class HomeMobilePortrait extends StatelessWidget { - final GlobalKey _scaffoldKey = GlobalKey(); - HomeMobilePortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - key: _scaffoldKey, - drawer: AppDrawer(), - body: Column( - children: [ - Padding( - padding: const EdgeInsets.all(16), - child: IconButton( - icon: Icon(Icons.menu, size: 30), - onPressed: () { - _scaffoldKey.currentState.openDrawer(); - }, - ), - ) - ], - ), - ); - } -} - -class HomeMobileLandscape extends StatelessWidget { - const HomeMobileLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Row(children: [ - AppDrawer() - ],), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/views/home/home_view_tablet.dart b/031-responsive-architecture-provider/01-starting/lib/views/home/home_view_tablet.dart deleted file mode 100644 index 0b40fb2e..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/views/home/home_view_tablet.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer.dart'; - -class HomeViewTablet extends StatelessWidget { - const HomeViewTablet({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var children = [ - Expanded( - child: Container(), - ), - AppDrawer() - ]; - var orientation = MediaQuery.of(context).orientation; - return Scaffold( - body: orientation == Orientation.portrait - ? Column(children: children) - : Row(children: children.reversed.toList()), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer.dart b/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer.dart deleted file mode 100644 index fc7c602b..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer_mobile.dart'; -import 'package:responsive_architecture/widgets/drawer_option/drawer_option.dart'; - -import 'app_drawer_tablet.dart'; - -class AppDrawer extends StatelessWidget { - const AppDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: AppDrawerMobile(), - tablet: OrientationLayout( - portrait: AppDrawerTabletPortrait(), - landscape: AppDrawerTabletLandscape(), - ), - ); - } - - static List getDrawerOptions() { - return [ - DrawerOption( - title: 'Images', - iconData: Icons.image, - ), - DrawerOption( - title: 'Reports', - iconData: Icons.photo_filter, - ), - DrawerOption( - title: 'Incidents', - iconData: Icons.message, - ), - DrawerOption( - title: 'Settings', - iconData: Icons.settings, - ), - ]; - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer_mobile.dart b/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer_mobile.dart deleted file mode 100644 index 8ef7d60a..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app_drawer.dart'; - -class AppDrawerMobile extends StatelessWidget { - const AppDrawerMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var orientation = MediaQuery.of(context).orientation; - return Container( - width: orientation == Orientation.portrait ? 250 : 100, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Column(children: AppDrawer.getDrawerOptions(),), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer_tablet.dart b/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer_tablet.dart deleted file mode 100644 index aab8d9f7..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/widgets/app_drawer/app_drawer_tablet.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app_drawer.dart'; - -class AppDrawerTabletPortrait extends StatelessWidget { - const AppDrawerTabletPortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 130, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Row( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} - -class AppDrawerTabletLandscape extends StatelessWidget { - const AppDrawerTabletLandscape({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 250, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Column( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option.dart b/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option.dart deleted file mode 100644 index e373fef0..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; - -import 'drawer_option_mobile.dart'; -import 'drawer_option_tablet.dart'; - -class DrawerOption extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOption({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: OrientationLayout( - landscape: DrawerOptionMobileLandscape( - iconData: iconData, - ), - portrait: DrawerOptionMobilePortrait( - title: title, - iconData: iconData, - ), - ), - tablet: OrientationLayout( - portrait: DrawerOptionTabletPortrait( - iconData: iconData, - title: title, - ), - landscape: DrawerOptionMobilePortrait( - iconData: iconData, - title: title, - ), - ), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option_mobile.dart b/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option_mobile.dart deleted file mode 100644 index f57c6abe..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option_mobile.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; - -class DrawerOptionMobilePortrait extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOptionMobilePortrait({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.only(left: 25), - height: 80, - child: Row( - children: [ - Icon( - iconData, - size: 25, - ), - SizedBox( - width: 25, - ), - Text( - title, - style: TextStyle(fontSize: 21), - ) - ], - ), - ); - } -} - -class DrawerOptionMobileLandscape extends StatelessWidget { - final IconData iconData; - const DrawerOptionMobileLandscape({Key key, this.iconData}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 70, - alignment: Alignment.center, - child: Icon(iconData), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option_tablet.dart b/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option_tablet.dart deleted file mode 100644 index 73318dfc..00000000 --- a/031-responsive-architecture-provider/01-starting/lib/widgets/drawer_option/drawer_option_tablet.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -class DrawerOptionTabletPortrait extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOptionTabletPortrait({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 152, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - iconData, - size: 45, - ), - Text(title, style: TextStyle(fontSize: 20)), - ], - ), - ); - } -} diff --git a/031-responsive-architecture-provider/01-starting/pubspec.lock b/031-responsive-architecture-provider/01-starting/pubspec.lock deleted file mode 100644 index 9fba4513..00000000 --- a/031-responsive-architecture-provider/01-starting/pubspec.lock +++ /dev/null @@ -1,229 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.12.13+hotfix.5 <2.0.0" diff --git a/031-responsive-architecture-provider/01-starting/pubspec.yaml b/031-responsive-architecture-provider/01-starting/pubspec.yaml deleted file mode 100644 index cfd71a15..00000000 --- a/031-responsive-architecture-provider/01-starting/pubspec.yaml +++ /dev/null @@ -1,67 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/031-responsive-architecture-provider/01-starting/test/widget_test.dart b/031-responsive-architecture-provider/01-starting/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/031-responsive-architecture-provider/01-starting/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/.flutter-plugins-dependencies b/031-responsive-architecture-provider/02-final-state-implementation/.flutter-plugins-dependencies deleted file mode 100644 index 1c3b13dc..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"android":[{"name":"shared_preferences","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences-0.5.7+3/","dependencies":[]}],"macos":[{"name":"shared_preferences_macos","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_macos-0.0.1+10/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"shared_preferences_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/shared_preferences_web-0.1.2+7/","dependencies":[]}]},"dependencyGraph":[{"name":"shared_preferences","dependencies":["shared_preferences_macos","shared_preferences_web"]},{"name":"shared_preferences_macos","dependencies":[]},{"name":"shared_preferences_web","dependencies":[]}],"date_created":"2020-06-18 21:49:10.378346","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/031-responsive-architecture-provider/02-final-state-implementation/.gitignore b/031-responsive-architecture-provider/02-final-state-implementation/.gitignore deleted file mode 100644 index c87d50a3..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/.gitignore +++ /dev/null @@ -1,73 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/031-responsive-architecture-provider/02-final-state-implementation/.metadata b/031-responsive-architecture-provider/02-final-state-implementation/.metadata deleted file mode 100644 index 1cbe9ad7..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/.metadata +++ /dev/null @@ -1,10 +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: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 - channel: stable - -project_type: app diff --git a/031-responsive-architecture-provider/02-final-state-implementation/README.md b/031-responsive-architecture-provider/02-final-state-implementation/README.md deleted file mode 100644 index 3e8ec65e..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# responsive_architecture - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/datamodels/drawer_item_data.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/datamodels/drawer_item_data.dart deleted file mode 100644 index 08a2fde5..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/datamodels/drawer_item_data.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class DrawerItemData { - final String title; - final IconData iconData; - - DrawerItemData({ - this.title, - this.iconData, - }); -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/enums/device_screen_type.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/enums/device_screen_type.dart deleted file mode 100644 index 4289f72c..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/enums/device_screen_type.dart +++ /dev/null @@ -1,5 +0,0 @@ -enum DeviceScreenType { - Mobile, - Tablet, - Desktop -} \ No newline at end of file diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/main.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/main.dart deleted file mode 100644 index 602c3954..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/main.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:device_preview/device_preview.dart'; -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/views/home/home_view.dart'; - -void main() => runApp(DevicePreview(builder: (context) => MyApp())); - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return MaterialApp( - builder: DevicePreview.appBuilder, - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomeView()); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/orientation_layout.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/orientation_layout.dart deleted file mode 100644 index 7ebcacaf..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/orientation_layout.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; - -class OrientationLayout extends StatelessWidget { - final Widget Function(BuildContext) landscape; - final Widget Function(BuildContext) portrait; - const OrientationLayout({ - Key key, - this.landscape, - this.portrait, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder( - builder: (context, boxConstraints) { - var orientation = MediaQuery.of(context).orientation; - if (orientation == Orientation.landscape) { - if (landscape != null) { - return landscape(context); - } - } - - return portrait(context); - }, - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/responsive_builder.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/responsive_builder.dart deleted file mode 100644 index 4fac7cf2..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/responsive_builder.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/sizing_information.dart'; -import 'package:responsive_architecture/utils/ui_utils.dart'; - -class ResponsiveBuilder extends StatelessWidget { - final Widget Function( - BuildContext context, - SizingInformation sizingInformation, - ) builder; - const ResponsiveBuilder({Key key, this.builder}) : super(key: key); - - @override - Widget build(BuildContext context) { - return LayoutBuilder(builder: (context, boxConstraints) { - var mediaQuery = MediaQuery.of(context); - var sizingInformation = SizingInformation( - deviceScreenType: getDeviceType(mediaQuery), - screenSize: mediaQuery.size, - localWidgetSize: - Size(boxConstraints.maxWidth, boxConstraints.maxHeight), - ); - return builder(context, sizingInformation); - }); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/screen_type_layout.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/screen_type_layout.dart deleted file mode 100644 index 0bf4a92a..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/screen_type_layout.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; -import 'package:responsive_architecture/responsive/responsive_builder.dart'; - -class ScreenTypeLayout extends StatelessWidget { - final Widget mobile; - final Widget tablet; - final Widget desktop; - const ScreenTypeLayout({ - Key key, - this.mobile, - this.tablet, - this.desktop, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - if (sizingInformation.deviceScreenType == DeviceScreenType.Tablet) { - if (tablet != null) { - return tablet; - } - } - - if (sizingInformation.deviceScreenType == DeviceScreenType.Desktop) { - if (desktop != null) { - return desktop; - } - } - - return mobile; - }, - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/sizing_information.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/sizing_information.dart deleted file mode 100644 index a2c84863..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/responsive/sizing_information.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -class SizingInformation { - final DeviceScreenType deviceScreenType; - final Size screenSize; - final Size localWidgetSize; - - SizingInformation({ - this.deviceScreenType, - this.screenSize, - this.localWidgetSize, - }); - - @override - String toString() { - return 'DeviceType:$deviceScreenType ScreenSize:$screenSize LocalWidgetSize:$localWidgetSize'; - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/utils/ui_utils.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/utils/ui_utils.dart deleted file mode 100644 index 7632593b..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/utils/ui_utils.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_architecture/enums/device_screen_type.dart'; - -DeviceScreenType getDeviceType(MediaQueryData mediaQuery) { - double deviceWidth = mediaQuery.size.shortestSide; - - if (deviceWidth > 950) { - return DeviceScreenType.Desktop; - } - - if (deviceWidth > 600) { - return DeviceScreenType.Tablet; - } - - return DeviceScreenType.Mobile; -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/viewmodels/home_viewmodel.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/viewmodels/home_viewmodel.dart deleted file mode 100644 index 472eeb8a..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/viewmodels/home_viewmodel.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomeViewModel extends ChangeNotifier { - String title = 'default'; - - void initialise() { - title = 'initialised'; - notifyListeners(); - } - - int counter = 0; - void updateTitle() { - counter++; - title = '$counter'; - notifyListeners(); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view.dart deleted file mode 100644 index 47d82272..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; -import 'package:responsive_architecture/viewmodels/home_viewmodel.dart'; -import 'package:responsive_architecture/widgets/base_widget.dart'; - -import 'home_view_mobile.dart'; -import 'home_view_tablet.dart'; - -class HomeView extends StatelessWidget { - @override - Widget build(BuildContext context) { - print('Rebuild'); - return BaseWidget( - viewModel: HomeViewModel(), - onModelReady: (model) => model.initialise(), - child: ScreenTypeLayout( - mobile: OrientationLayout( - portrait: (context) => HomeMobilePortrait(), - landscape: (context) => HomeMobileLandscape(), - ), - tablet: HomeViewTablet(), - ), - ); - } -} - -class SecondView extends StatelessWidget { - const SecondView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.red, - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view_mobile.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view_mobile.dart deleted file mode 100644 index dc555bee..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view_mobile.dart +++ /dev/null @@ -1,72 +0,0 @@ -/// Contains the widgets that will be used for Mobile layout of home, -/// portrait and landscape - -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/viewmodels/home_viewmodel.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer.dart'; -import 'package:responsive_architecture/widgets/base_model_widget.dart'; - -import 'home_view.dart'; - -class HomeMobilePortrait extends BaseModelWidget { - final GlobalKey _scaffoldKey = GlobalKey(); - - @override - Widget build(BuildContext context, HomeViewModel model) { - return Scaffold( - key: _scaffoldKey, - drawer: AppDrawer(), - floatingActionButton: FloatingActionButton( - onPressed: () { - model.updateTitle(); - }, - ), - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(16), - child: IconButton( - icon: Icon(Icons.menu, size: 30), - onPressed: () { - _scaffoldKey?.currentState?.openDrawer(); - }, - ), - ), - Expanded( - child: Center( - child: Text(model.title), - ), - ) - ], - ), - ); - } -} - -class HomeMobileLandscape extends BaseModelWidget { - @override - Widget build(BuildContext context, HomeViewModel model) { - return Scaffold( - floatingActionButton: FloatingActionButton( - onPressed: () { - Navigator.of(context) - .push(MaterialPageRoute(builder: (context) => SecondView())); - }, - ), - body: Row( - children: [ - AppDrawer(), - Expanded( - child: Center( - child: Text( - model.title, - style: TextStyle(fontSize: 35), - ), - ), - ) - ], - ), - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view_tablet.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view_tablet.dart deleted file mode 100644 index 0b40fb2e..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/views/home/home_view_tablet.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer.dart'; - -class HomeViewTablet extends StatelessWidget { - const HomeViewTablet({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var children = [ - Expanded( - child: Container(), - ), - AppDrawer() - ]; - var orientation = MediaQuery.of(context).orientation; - return Scaffold( - body: orientation == Orientation.portrait - ? Column(children: children) - : Row(children: children.reversed.toList()), - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer.dart deleted file mode 100644 index 6e4b1d51..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; -import 'package:responsive_architecture/widgets/app_drawer/app_drawer_mobile.dart'; -import 'package:responsive_architecture/widgets/drawer_option/drawer_option.dart'; - -import 'app_drawer_tablet.dart'; - -class AppDrawer extends StatelessWidget { - const AppDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: AppDrawerMobile(), - tablet: OrientationLayout( - portrait: (context) => AppDrawerTabletPortrait(), - landscape: (context) => AppDrawerTabletLandscape(), - ), - ); - } - - static List getDrawerOptions() { - return [ - DrawerOption( - title: 'Images', - iconData: Icons.image, - ), - DrawerOption( - title: 'Reports', - iconData: Icons.photo_filter, - ), - DrawerOption( - title: 'Incidents', - iconData: Icons.message, - ), - DrawerOption( - title: 'Settings', - iconData: Icons.settings, - ), - ]; - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer_mobile.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer_mobile.dart deleted file mode 100644 index 8ef7d60a..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app_drawer.dart'; - -class AppDrawerMobile extends StatelessWidget { - const AppDrawerMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var orientation = MediaQuery.of(context).orientation; - return Container( - width: orientation == Orientation.portrait ? 250 : 100, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Column(children: AppDrawer.getDrawerOptions(),), - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer_tablet.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer_tablet.dart deleted file mode 100644 index 823e4c96..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/app_drawer/app_drawer_tablet.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'app_drawer.dart'; - -class AppDrawerTabletPortrait extends StatelessWidget { - const AppDrawerTabletPortrait({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 130, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Row( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} - -class AppDrawerTabletLandscape extends StatelessWidget { - @override - Widget build(BuildContext context) { - return Container( - width: 250, - decoration: BoxDecoration(color: Colors.white, boxShadow: [ - BoxShadow( - blurRadius: 16, - color: Colors.black12, - ) - ]), - child: Column( - children: AppDrawer.getDrawerOptions(), - ), - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/base_model_widget.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/base_model_widget.dart deleted file mode 100644 index d7c539e8..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/base_model_widget.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -abstract class BaseModelWidget extends Widget { - @protected - Widget build(BuildContext context, T model); - - @override - DataProviderElement createElement() => DataProviderElement(this); -} - -class DataProviderElement extends ComponentElement { - DataProviderElement(BaseModelWidget widget) : super(widget); - - @override - BaseModelWidget get widget => super.widget; - - @override - Widget build() => widget.build(this, Provider.of(this)); - - @override - void update(BaseModelWidget newWidget) { - super.update(newWidget); - assert(widget == newWidget); - rebuild(); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/base_widget.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/base_widget.dart deleted file mode 100644 index d4b9dcfe..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/base_widget.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class BaseWidget extends StatefulWidget { - final Widget child; - final Function(T) onModelReady; - final T viewModel; - BaseWidget({ - Key key, - this.child, - this.onModelReady, - this.viewModel, - }) : super(key: key); - - @override - _BaseWidgetState createState() => _BaseWidgetState(); -} - -class _BaseWidgetState extends State> { - T _model; - - @override - void initState() { - super.initState(); - _model = widget.viewModel; - - if (widget.onModelReady != null) { - widget.onModelReady(_model); - } - } - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => _model, - child: widget.child, - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option.dart deleted file mode 100644 index 538aa3da..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_architecture/datamodels/drawer_item_data.dart'; -import 'package:responsive_architecture/responsive/orientation_layout.dart'; -import 'package:responsive_architecture/responsive/screen_type_layout.dart'; - -import 'drawer_option_mobile.dart'; -import 'drawer_option_tablet.dart'; - -class DrawerOption extends StatelessWidget { - final String title; - final IconData iconData; - const DrawerOption({ - Key key, - this.title, - this.iconData, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Provider.value( - value: DrawerItemData(title: title, iconData: iconData), - child: ScreenTypeLayout( - mobile: OrientationLayout( - landscape: (context) => DrawerOptionMobileLandscape(), - portrait: (context) => DrawerOptionMobilePortrait(), - ), - tablet: OrientationLayout( - portrait: (context) => DrawerOptionTabletPortrait(), - landscape: (context) => DrawerOptionMobilePortrait(), - ), - ), - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option_mobile.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option_mobile.dart deleted file mode 100644 index 211e0e6e..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option_mobile.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_architecture/datamodels/drawer_item_data.dart'; -import 'package:responsive_architecture/widgets/base_model_widget.dart'; - -class DrawerOptionMobilePortrait extends BaseModelWidget { - @override - Widget build(BuildContext context, DrawerItemData data) { - return Container( - padding: const EdgeInsets.only(left: 25), - height: 80, - child: Row( - children: [ - Icon( - data.iconData, - size: 25, - ), - SizedBox( - width: 25, - ), - Text( - data.title, - style: TextStyle(fontSize: 21), - ) - ], - ), - ); - } -} - -class DrawerOptionMobileLandscape extends BaseModelWidget { - @override - Widget build(BuildContext context, DrawerItemData data) { - return Container( - height: 70, - alignment: Alignment.center, - child: Icon(data.iconData), - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option_tablet.dart b/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option_tablet.dart deleted file mode 100644 index 626149fc..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/lib/widgets/drawer_option/drawer_option_tablet.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_architecture/datamodels/drawer_item_data.dart'; - -class DrawerOptionTabletPortrait extends StatelessWidget { - @override - Widget build(BuildContext context) { - var itemData = Provider.of(context); - return Container( - width: 152, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Icon( - itemData.iconData, - size: 45, - ), - Text(itemData.title, style: TextStyle(fontSize: 20)), - ], - ), - ); - } -} diff --git a/031-responsive-architecture-provider/02-final-state-implementation/pubspec.lock b/031-responsive-architecture-provider/02-final-state-implementation/pubspec.lock deleted file mode 100644 index 724f1e84..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/pubspec.lock +++ /dev/null @@ -1,243 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - device_preview: - dependency: "direct main" - description: - name: device_preview - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - font_awesome_flutter: - dependency: transitive - description: - name: font_awesome_flutter - url: "https://pub.dartlang.org" - source: hosted - version: "8.8.1" - freezed_annotation: - dependency: transitive - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.1" - http: - dependency: transitive - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0+2" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - json_annotation: - dependency: transitive - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.7+3" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/031-responsive-architecture-provider/02-final-state-implementation/pubspec.yaml b/031-responsive-architecture-provider/02-final-state-implementation/pubspec.yaml deleted file mode 100644 index cd062114..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/pubspec.yaml +++ /dev/null @@ -1,68 +0,0 @@ -name: responsive_architecture -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - device_preview: ^0.4.5 - provider: ^4.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/031-responsive-architecture-provider/02-final-state-implementation/test/widget_test.dart b/031-responsive-architecture-provider/02-final-state-implementation/test/widget_test.dart deleted file mode 100644 index 2667d74a..00000000 --- a/031-responsive-architecture-provider/02-final-state-implementation/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:responsive_architecture/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/032-flutter-web-part1/.firebaserc b/032-flutter-web-part1/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/032-flutter-web-part1/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/032-flutter-web-part1/.gitignore b/032-flutter-web-part1/.gitignore deleted file mode 100644 index 36a616eb..00000000 --- a/032-flutter-web-part1/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/032-flutter-web-part1/.metadata b/032-flutter-web-part1/.metadata deleted file mode 100644 index c17efdcf..00000000 --- a/032-flutter-web-part1/.metadata +++ /dev/null @@ -1,10 +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: 8e0799a657051bf540d98b8aecf9cfa1325f3f71 - channel: master - -project_type: app diff --git a/032-flutter-web-part1/README.md b/032-flutter-web-part1/README.md deleted file mode 100644 index e42c305e..00000000 --- a/032-flutter-web-part1/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# the_basics - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/032-flutter-web-part1/assets/fonts/OpenSans-ExtraBold.ttf b/032-flutter-web-part1/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/032-flutter-web-part1/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/032-flutter-web-part1/assets/fonts/OpenSans-Regular.ttf b/032-flutter-web-part1/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/032-flutter-web-part1/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/032-flutter-web-part1/assets/logo.png b/032-flutter-web-part1/assets/logo.png deleted file mode 100644 index bcd4c4b9..00000000 Binary files a/032-flutter-web-part1/assets/logo.png and /dev/null differ diff --git a/032-flutter-web-part1/firebase.json b/032-flutter-web-part1/firebase.json deleted file mode 100644 index 66037326..00000000 --- a/032-flutter-web-part1/firebase.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosting": { - "public": "build/web", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/032-flutter-web-part1/lib/main.dart b/032-flutter-web-part1/lib/main.dart deleted file mode 100644 index 7cba1883..00000000 --- a/032-flutter-web-part1/lib/main.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/views/home/home_view.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - textTheme: Theme.of(context).textTheme.apply(fontFamily: 'Open Sans'), - ), - home: HomeView(), - ); - } -} diff --git a/032-flutter-web-part1/lib/views/home/home_view.dart b/032-flutter-web-part1/lib/views/home/home_view.dart deleted file mode 100644 index 7983a9c1..00000000 --- a/032-flutter-web-part1/lib/views/home/home_view.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/centered_view/centered_view.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: Colors.white, - body: CenteredView( - child: Column( - children: [ - NavigationBar(), - Expanded( - child: Row( - children: [ - CourseDetails(), - Expanded( - child: Center( - child: CallToAction('Join Course'), - ), - ) - ], - ), - ) - ], - ), - ), - ); - } -} diff --git a/032-flutter-web-part1/lib/widgets/call_to_action/call_to_action.dart b/032-flutter-web-part1/lib/widgets/call_to_action/call_to_action.dart deleted file mode 100644 index 3d511e5d..00000000 --- a/032-flutter-web-part1/lib/widgets/call_to_action/call_to_action.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; - -class CallToAction extends StatelessWidget { - final String title; - CallToAction(this.title); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15), - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: Color.fromARGB(255, 31, 229, 146), - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/032-flutter-web-part1/lib/widgets/centered_view/centered_view.dart b/032-flutter-web-part1/lib/widgets/centered_view/centered_view.dart deleted file mode 100644 index 1aed138b..00000000 --- a/032-flutter-web-part1/lib/widgets/centered_view/centered_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class CenteredView extends StatelessWidget { - final Widget child; - const CenteredView({Key key, this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 60), - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 1200), - child: child, - ), - ); - } -} diff --git a/032-flutter-web-part1/lib/widgets/course_details/course_details.dart b/032-flutter-web-part1/lib/widgets/course_details/course_details.dart deleted file mode 100644 index 0e4d85a6..00000000 --- a/032-flutter-web-part1/lib/widgets/course_details/course_details.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; - -class CourseDetails extends StatelessWidget { - const CourseDetails({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 600, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'FLUTTER WEB.\nTHE BASICS', - style: TextStyle(fontWeight: FontWeight.w800, height: 0.9, fontSize: 80), - ), - SizedBox( - height: 30, - ), - Text( - 'In this course we will go over the basics of using Flutter Web for website development. Topics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.', - style: TextStyle( - fontSize: 21, - height: 1.7, - )) - ], - ), - ); - } -} diff --git a/032-flutter-web-part1/lib/widgets/navigation_bar/navigation_bar.dart b/032-flutter-web-part1/lib/widgets/navigation_bar/navigation_bar.dart deleted file mode 100644 index 57013b1d..00000000 --- a/032-flutter-web-part1/lib/widgets/navigation_bar/navigation_bar.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationBar extends StatelessWidget { - const NavigationBar({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - SizedBox( - height: 80, - width: 150, - child: Image.asset('assets/logo.png'), - ), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - _NavBarItem('Episodes'), - SizedBox( - width: 60, - ), - _NavBarItem('About'), - ], - ) - ], - ), - ); - } -} - -class _NavBarItem extends StatelessWidget { - final String title; - const _NavBarItem(this.title); - - @override - Widget build(BuildContext context) { - return Text( - title, - style: TextStyle(fontSize: 18), - ); - } -} diff --git a/032-flutter-web-part1/pubspec.lock b/032-flutter-web-part1/pubspec.lock deleted file mode 100644 index 066a096b..00000000 --- a/032-flutter-web-part1/pubspec.lock +++ /dev/null @@ -1,146 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/032-flutter-web-part1/pubspec.yaml b/032-flutter-web-part1/pubspec.yaml deleted file mode 100644 index 73cff490..00000000 --- a/032-flutter-web-part1/pubspec.yaml +++ /dev/null @@ -1,73 +0,0 @@ -name: the_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/logo.png - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/032-flutter-web-part1/test/widget_test.dart b/032-flutter-web-part1/test/widget_test.dart deleted file mode 100644 index b9e0d165..00000000 --- a/032-flutter-web-part1/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:the_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/032-flutter-web-part1/web/index.html b/032-flutter-web-part1/web/index.html deleted file mode 100644 index b7d4703b..00000000 --- a/032-flutter-web-part1/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - the_basics - - - - - diff --git a/033-flutter-web-part2-responsive/.firebaserc b/033-flutter-web-part2-responsive/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/033-flutter-web-part2-responsive/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/033-flutter-web-part2-responsive/.gitignore b/033-flutter-web-part2-responsive/.gitignore deleted file mode 100644 index 36a616eb..00000000 --- a/033-flutter-web-part2-responsive/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/033-flutter-web-part2-responsive/.metadata b/033-flutter-web-part2-responsive/.metadata deleted file mode 100644 index c17efdcf..00000000 --- a/033-flutter-web-part2-responsive/.metadata +++ /dev/null @@ -1,10 +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: 8e0799a657051bf540d98b8aecf9cfa1325f3f71 - channel: master - -project_type: app diff --git a/033-flutter-web-part2-responsive/README.md b/033-flutter-web-part2-responsive/README.md deleted file mode 100644 index e42c305e..00000000 --- a/033-flutter-web-part2-responsive/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# the_basics - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/033-flutter-web-part2-responsive/assets/fonts/OpenSans-ExtraBold.ttf b/033-flutter-web-part2-responsive/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/033-flutter-web-part2-responsive/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/033-flutter-web-part2-responsive/assets/fonts/OpenSans-Regular.ttf b/033-flutter-web-part2-responsive/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/033-flutter-web-part2-responsive/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/033-flutter-web-part2-responsive/assets/logo.png b/033-flutter-web-part2-responsive/assets/logo.png deleted file mode 100644 index bcd4c4b9..00000000 Binary files a/033-flutter-web-part2-responsive/assets/logo.png and /dev/null differ diff --git a/033-flutter-web-part2-responsive/firebase.json b/033-flutter-web-part2-responsive/firebase.json deleted file mode 100644 index 66037326..00000000 --- a/033-flutter-web-part2-responsive/firebase.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosting": { - "public": "build/web", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/033-flutter-web-part2-responsive/lib/constants/app_colors.dart b/033-flutter-web-part2-responsive/lib/constants/app_colors.dart deleted file mode 100644 index 4524aca0..00000000 --- a/033-flutter-web-part2-responsive/lib/constants/app_colors.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color primaryColor = Color.fromARGB(255, 31, 229, 146); \ No newline at end of file diff --git a/033-flutter-web-part2-responsive/lib/main.dart b/033-flutter-web-part2-responsive/lib/main.dart deleted file mode 100644 index 7cba1883..00000000 --- a/033-flutter-web-part2-responsive/lib/main.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/views/home/home_view.dart'; - -void main() => runApp(MyApp()); - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - textTheme: Theme.of(context).textTheme.apply(fontFamily: 'Open Sans'), - ), - home: HomeView(), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/views/home/home_content_desktop.dart b/033-flutter-web-part2-responsive/lib/views/home/home_content_desktop.dart deleted file mode 100644 index 4fab7a21..00000000 --- a/033-flutter-web-part2-responsive/lib/views/home/home_content_desktop.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentDesktop extends StatelessWidget { - const HomeContentDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Row( - children: [ - CourseDetails(), - Expanded( - child: Center( - child: CallToAction('Join Course'), - ), - ) - ], - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/views/home/home_content_mobile.dart b/033-flutter-web-part2-responsive/lib/views/home/home_content_mobile.dart deleted file mode 100644 index 028c8d38..00000000 --- a/033-flutter-web-part2-responsive/lib/views/home/home_content_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentMobile extends StatelessWidget { - const HomeContentMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CourseDetails(), - SizedBox( - height: 100, - ), - CallToAction('Join Course'), - ], - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/views/home/home_view.dart b/033-flutter-web-part2-responsive/lib/views/home/home_view.dart deleted file mode 100644 index 11647520..00000000 --- a/033-flutter-web-part2-responsive/lib/views/home/home_view.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/views/home/home_content_desktop.dart'; -import 'package:the_basics/views/home/home_content_mobile.dart'; -import 'package:the_basics/widgets/centered_view/centered_view.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Scaffold( - drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? NavigationDrawer() - : null, - backgroundColor: Colors.white, - body: CenteredView( - child: Column( - children: [ - NavigationBar(), - Expanded( - child: ScreenTypeLayout( - mobile: HomeContentMobile(), - desktop: HomeContentDesktop(), - )) - ], - ), - ), - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action.dart b/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action.dart deleted file mode 100644 index d5c72e8a..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_mobile.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_tablet_desktop.dart'; - -class CallToAction extends StatelessWidget { - final String title; - CallToAction(this.title); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: CallToActionMobile(title), - tablet: CallToActionTabletDesktop(title), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action_mobile.dart b/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action_mobile.dart deleted file mode 100644 index d2455218..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action_mobile.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionMobile extends StatelessWidget { - final String title; - const CallToActionMobile(this.title); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - alignment: Alignment.center, - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart b/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart deleted file mode 100644 index 0ea18c80..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionTabletDesktop extends StatelessWidget { - final String title; - const CallToActionTabletDesktop(this.title); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15), - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/centered_view/centered_view.dart b/033-flutter-web-part2-responsive/lib/widgets/centered_view/centered_view.dart deleted file mode 100644 index 1aed138b..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/centered_view/centered_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class CenteredView extends StatelessWidget { - final Widget child; - const CenteredView({Key key, this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 60), - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 1200), - child: child, - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/course_details/course_details.dart b/033-flutter-web-part2-responsive/lib/widgets/course_details/course_details.dart deleted file mode 100644 index 7e715632..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/course_details/course_details.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class CourseDetails extends StatelessWidget { - const CourseDetails({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - var textAlignment = - sizingInformation.deviceScreenType == DeviceScreenType.desktop - ? TextAlign.left - : TextAlign.center; - double titleSize = - sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? 50 - : 80; - - double descriptionSize = - sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? 16 - : 21; - - return Container( - width: 600, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'FLUTTER WEB.\nTHE BASICS', - style: TextStyle( - fontWeight: FontWeight.w800, - height: 0.9, - fontSize: titleSize), - textAlign: textAlignment, - ), - SizedBox( - height: 30, - ), - Text( - 'In this course we will go over the basics of using Flutter Web for website development. Topics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.', - style: TextStyle( - fontSize: descriptionSize, - height: 1.7, - ), - textAlign: textAlignment, - ) - ], - ), - ); - }, - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navbar_item.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navbar_item.dart deleted file mode 100644 index be388b46..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navbar_item.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavBarItem extends StatelessWidget { - final String title; - const NavBarItem(this.title); - - @override - Widget build(BuildContext context) { - return Text( - title, - style: TextStyle(fontSize: 18), - ); - } -} \ No newline at end of file diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navbar_logo.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navbar_logo.dart deleted file mode 100644 index 483fe20f..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navbar_logo.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavBarLogo extends StatelessWidget { - const NavBarLogo({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 80, - width: 150, - child: Image.asset('assets/logo.png'), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar.dart deleted file mode 100644 index a09d1e34..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_tablet_desktop.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_mobile.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class NavigationBar extends StatelessWidget { - const NavigationBar({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: NavigationBarMobile(), - tablet: NavigationBarTabletDesktop(), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar_mobile.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar_mobile.dart deleted file mode 100644 index 387f852c..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_logo.dart'; - -class NavigationBarMobile extends StatelessWidget { - const NavigationBarMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 80, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: Icon(Icons.menu), - onPressed: () {}, - ), - NavBarLogo() - ], - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart deleted file mode 100644 index a9f9e9b7..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'navbar_item.dart'; -import 'navbar_logo.dart'; - -class NavigationBarTabletDesktop extends StatelessWidget { - const NavigationBarTabletDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - NavBarLogo(), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - NavBarItem('Episodes'), - SizedBox( - width: 60, - ), - NavBarItem('About'), - ], - ) - ], - ), - ); - } -} \ No newline at end of file diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/drawer_item.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/drawer_item.dart deleted file mode 100644 index 3ed087e4..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/drawer_item.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_item.dart'; - -class DrawerItem extends StatelessWidget { - final String title; - final IconData icon; - const DrawerItem(this.title, this.icon); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(left: 30, top: 60), - child: Row( - children: [ - Icon(icon), - SizedBox( - width: 30, - ), - NavBarItem(title) - ], - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/navigation_drawer.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/navigation_drawer.dart deleted file mode 100644 index 58f901af..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/navigation_drawer.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_drawer/drawer_item.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer_header.dart'; - -class NavigationDrawer extends StatelessWidget { - const NavigationDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 300, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(color: Colors.black12, blurRadius: 16), - ], - ), - child: Column( - children: [ - NavigationDrawerHeader(), - DrawerItem('Episodes', Icons.videocam), - DrawerItem('About', Icons.help), - ], - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/navigation_drawer_header.dart b/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/navigation_drawer_header.dart deleted file mode 100644 index 0b96e2af..00000000 --- a/033-flutter-web-part2-responsive/lib/widgets/navigation_drawer/navigation_drawer_header.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class NavigationDrawerHeader extends StatelessWidget { - const NavigationDrawerHeader({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 150, - color: primaryColor, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'SKILL UP NOW', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white), - ), - Text( - 'TAP HERE', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ); - } -} diff --git a/033-flutter-web-part2-responsive/pubspec.lock b/033-flutter-web-part2-responsive/pubspec.lock deleted file mode 100644 index 1f0bfea7..00000000 --- a/033-flutter-web-part2-responsive/pubspec.lock +++ /dev/null @@ -1,153 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - responsive_builder: - dependency: "direct main" - description: - name: responsive_builder - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/033-flutter-web-part2-responsive/pubspec.yaml b/033-flutter-web-part2-responsive/pubspec.yaml deleted file mode 100644 index 3351bd41..00000000 --- a/033-flutter-web-part2-responsive/pubspec.yaml +++ /dev/null @@ -1,74 +0,0 @@ -name: the_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - responsive_builder: ^0.2.0+2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/logo.png - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/033-flutter-web-part2-responsive/test/widget_test.dart b/033-flutter-web-part2-responsive/test/widget_test.dart deleted file mode 100644 index b9e0d165..00000000 --- a/033-flutter-web-part2-responsive/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:the_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/033-flutter-web-part2-responsive/web/index.html b/033-flutter-web-part2-responsive/web/index.html deleted file mode 100644 index b7d4703b..00000000 --- a/033-flutter-web-part2-responsive/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - the_basics - - - - - diff --git a/034-flutter-web-part3-template-layouts/.firebaserc b/034-flutter-web-part3-template-layouts/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/034-flutter-web-part3-template-layouts/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/034-flutter-web-part3-template-layouts/.gitignore b/034-flutter-web-part3-template-layouts/.gitignore deleted file mode 100644 index 36a616eb..00000000 --- a/034-flutter-web-part3-template-layouts/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/034-flutter-web-part3-template-layouts/.metadata b/034-flutter-web-part3-template-layouts/.metadata deleted file mode 100644 index c17efdcf..00000000 --- a/034-flutter-web-part3-template-layouts/.metadata +++ /dev/null @@ -1,10 +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: 8e0799a657051bf540d98b8aecf9cfa1325f3f71 - channel: master - -project_type: app diff --git a/034-flutter-web-part3-template-layouts/README.md b/034-flutter-web-part3-template-layouts/README.md deleted file mode 100644 index e42c305e..00000000 --- a/034-flutter-web-part3-template-layouts/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# the_basics - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/034-flutter-web-part3-template-layouts/assets/fonts/OpenSans-ExtraBold.ttf b/034-flutter-web-part3-template-layouts/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/034-flutter-web-part3-template-layouts/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/034-flutter-web-part3-template-layouts/assets/fonts/OpenSans-Regular.ttf b/034-flutter-web-part3-template-layouts/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/034-flutter-web-part3-template-layouts/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/034-flutter-web-part3-template-layouts/assets/logo.png b/034-flutter-web-part3-template-layouts/assets/logo.png deleted file mode 100644 index bcd4c4b9..00000000 Binary files a/034-flutter-web-part3-template-layouts/assets/logo.png and /dev/null differ diff --git a/034-flutter-web-part3-template-layouts/firebase.json b/034-flutter-web-part3-template-layouts/firebase.json deleted file mode 100644 index 66037326..00000000 --- a/034-flutter-web-part3-template-layouts/firebase.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosting": { - "public": "build/web", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/constants/app_colors.dart b/034-flutter-web-part3-template-layouts/lib/constants/app_colors.dart deleted file mode 100644 index 4524aca0..00000000 --- a/034-flutter-web-part3-template-layouts/lib/constants/app_colors.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color primaryColor = Color.fromARGB(255, 31, 229, 146); \ No newline at end of file diff --git a/034-flutter-web-part3-template-layouts/lib/locator.dart b/034-flutter-web-part3-template-layouts/lib/locator.dart deleted file mode 100644 index f68ca6b6..00000000 --- a/034-flutter-web-part3-template-layouts/lib/locator.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:the_basics/services/navigation_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); -} \ No newline at end of file diff --git a/034-flutter-web-part3-template-layouts/lib/main.dart b/034-flutter-web-part3-template-layouts/lib/main.dart deleted file mode 100644 index 135075f6..00000000 --- a/034-flutter-web-part3-template-layouts/lib/main.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/views/layout_template/layout_template.dart'; - -import 'locator.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - textTheme: Theme.of(context).textTheme.apply(fontFamily: 'Open Sans'), - ), - home: LayoutTemplate(), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/routing/route_names.dart b/034-flutter-web-part3-template-layouts/lib/routing/route_names.dart deleted file mode 100644 index c8aeef50..00000000 --- a/034-flutter-web-part3-template-layouts/lib/routing/route_names.dart +++ /dev/null @@ -1,3 +0,0 @@ -const String HomeRoute = 'home'; -const String AboutRoute = 'about'; -const String EpisodesRoute = 'episodes'; diff --git a/034-flutter-web-part3-template-layouts/lib/routing/router.dart b/034-flutter-web-part3-template-layouts/lib/routing/router.dart deleted file mode 100644 index c244e89d..00000000 --- a/034-flutter-web-part3-template-layouts/lib/routing/router.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/views/about/about_view.dart'; -import 'package:the_basics/views/episodes/episodes_view.dart'; -import 'package:the_basics/views/home/home_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case HomeRoute: - return _getPageRoute(HomeView(), settings.name); - case AboutRoute: - return _getPageRoute(AboutView(), settings.name); - case EpisodesRoute: - return _getPageRoute(EpisodesView(), settings.name); - default: - } -} - -PageRoute _getPageRoute(Widget child, String routeName) { - return _FadeRoute(child: child, routeName: routeName); -} - -class _FadeRoute extends PageRouteBuilder { - final Widget child; - final String routeName; - _FadeRoute({this.child, this.routeName}) - : super( - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) => - child, - settings: RouteSettings(name: routeName), - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => - FadeTransition( - opacity: animation, - child: child, - )); -} - diff --git a/034-flutter-web-part3-template-layouts/lib/services/navigation_service.dart b/034-flutter-web-part3-template-layouts/lib/services/navigation_service.dart deleted file mode 100644 index d4a51a00..00000000 --- a/034-flutter-web-part3-template-layouts/lib/services/navigation_service.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - final GlobalKey navigatorKey = GlobalKey(); - - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); - } - - void goBack() { - return navigatorKey.currentState.pop(); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/views/about/about_view.dart b/034-flutter-web-part3-template-layouts/lib/views/about/about_view.dart deleted file mode 100644 index 34741b6f..00000000 --- a/034-flutter-web-part3-template-layouts/lib/views/about/about_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class AboutView extends StatelessWidget { - const AboutView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.red, - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/views/episodes/episodes_view.dart b/034-flutter-web-part3-template-layouts/lib/views/episodes/episodes_view.dart deleted file mode 100644 index 132fcf6e..00000000 --- a/034-flutter-web-part3-template-layouts/lib/views/episodes/episodes_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class EpisodesView extends StatelessWidget { - const EpisodesView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.blue, - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/views/home/home_content_desktop.dart b/034-flutter-web-part3-template-layouts/lib/views/home/home_content_desktop.dart deleted file mode 100644 index 4fab7a21..00000000 --- a/034-flutter-web-part3-template-layouts/lib/views/home/home_content_desktop.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentDesktop extends StatelessWidget { - const HomeContentDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Row( - children: [ - CourseDetails(), - Expanded( - child: Center( - child: CallToAction('Join Course'), - ), - ) - ], - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/views/home/home_content_mobile.dart b/034-flutter-web-part3-template-layouts/lib/views/home/home_content_mobile.dart deleted file mode 100644 index 028c8d38..00000000 --- a/034-flutter-web-part3-template-layouts/lib/views/home/home_content_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentMobile extends StatelessWidget { - const HomeContentMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CourseDetails(), - SizedBox( - height: 100, - ), - CallToAction('Join Course'), - ], - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/views/home/home_view.dart b/034-flutter-web-part3-template-layouts/lib/views/home/home_view.dart deleted file mode 100644 index a138243d..00000000 --- a/034-flutter-web-part3-template-layouts/lib/views/home/home_view.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/views/home/home_content_desktop.dart'; -import 'package:the_basics/views/home/home_content_mobile.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: HomeContentMobile(), - desktop: HomeContentDesktop(), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/views/layout_template/layout_template.dart b/034-flutter-web-part3-template-layouts/lib/views/layout_template/layout_template.dart deleted file mode 100644 index b6d5030d..00000000 --- a/034-flutter-web-part3-template-layouts/lib/views/layout_template/layout_template.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/routing/router.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/centered_view/centered_view.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer.dart'; - -class LayoutTemplate extends StatelessWidget { - const LayoutTemplate({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Scaffold( - drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? NavigationDrawer() - : null, - backgroundColor: Colors.white, - body: CenteredView( - child: Column( - children: [ - NavigationBar(), - Expanded( - child: Navigator( - key: locator().navigatorKey, - onGenerateRoute: generateRoute, - initialRoute: HomeRoute, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action.dart b/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action.dart deleted file mode 100644 index d5c72e8a..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_mobile.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_tablet_desktop.dart'; - -class CallToAction extends StatelessWidget { - final String title; - CallToAction(this.title); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: CallToActionMobile(title), - tablet: CallToActionTabletDesktop(title), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action_mobile.dart b/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action_mobile.dart deleted file mode 100644 index d2455218..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action_mobile.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionMobile extends StatelessWidget { - final String title; - const CallToActionMobile(this.title); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - alignment: Alignment.center, - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart b/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart deleted file mode 100644 index 0ea18c80..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionTabletDesktop extends StatelessWidget { - final String title; - const CallToActionTabletDesktop(this.title); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15), - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/centered_view/centered_view.dart b/034-flutter-web-part3-template-layouts/lib/widgets/centered_view/centered_view.dart deleted file mode 100644 index 1aed138b..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/centered_view/centered_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class CenteredView extends StatelessWidget { - final Widget child; - const CenteredView({Key key, this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 60), - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 1200), - child: child, - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/course_details/course_details.dart b/034-flutter-web-part3-template-layouts/lib/widgets/course_details/course_details.dart deleted file mode 100644 index 7e715632..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/course_details/course_details.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class CourseDetails extends StatelessWidget { - const CourseDetails({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - var textAlignment = - sizingInformation.deviceScreenType == DeviceScreenType.desktop - ? TextAlign.left - : TextAlign.center; - double titleSize = - sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? 50 - : 80; - - double descriptionSize = - sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? 16 - : 21; - - return Container( - width: 600, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'FLUTTER WEB.\nTHE BASICS', - style: TextStyle( - fontWeight: FontWeight.w800, - height: 0.9, - fontSize: titleSize), - textAlign: textAlignment, - ), - SizedBox( - height: 30, - ), - Text( - 'In this course we will go over the basics of using Flutter Web for website development. Topics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.', - style: TextStyle( - fontSize: descriptionSize, - height: 1.7, - ), - textAlign: textAlignment, - ) - ], - ), - ); - }, - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navbar_item.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navbar_item.dart deleted file mode 100644 index 6dbe5adf..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navbar_item.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/navigation_service.dart'; - -class NavBarItem extends StatelessWidget { - final String title; - final String navigationPath; - const NavBarItem(this.title, this.navigationPath); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: () { - // DON'T EVER USE A SERVICE DIRECTLY IN THE UI TO CHANGE ANY KIND OF STATE - // SERVICES SHOULD ONLY BE USED FROM A VIEWMODEL - locator().navigateTo(navigationPath); - }, - child: Text( - title, - style: TextStyle(fontSize: 18), - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navbar_logo.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navbar_logo.dart deleted file mode 100644 index 483fe20f..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navbar_logo.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavBarLogo extends StatelessWidget { - const NavBarLogo({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 80, - width: 150, - child: Image.asset('assets/logo.png'), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar.dart deleted file mode 100644 index a09d1e34..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_tablet_desktop.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_mobile.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class NavigationBar extends StatelessWidget { - const NavigationBar({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: NavigationBarMobile(), - tablet: NavigationBarTabletDesktop(), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar_mobile.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar_mobile.dart deleted file mode 100644 index 7460b5ac..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar_mobile.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_logo.dart'; - -class NavigationBarMobile extends StatelessWidget { - const NavigationBarMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 80, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: Icon(Icons.menu), - onPressed: () { - Scaffold.of(context).openDrawer(); - }, - ), - NavBarLogo() - ], - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart deleted file mode 100644 index 01fa6710..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; - -import 'navbar_item.dart'; -import 'navbar_logo.dart'; - -class NavigationBarTabletDesktop extends StatelessWidget { - const NavigationBarTabletDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - NavBarLogo(), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - NavBarItem('Episodes', EpisodesRoute), - SizedBox( - width: 60, - ), - NavBarItem('About', AboutRoute), - ], - ) - ], - ), - ); - } -} \ No newline at end of file diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/drawer_item.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/drawer_item.dart deleted file mode 100644 index d800466a..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/drawer_item.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_item.dart'; - -class DrawerItem extends StatelessWidget { - final String title; - final IconData icon; - final String navigationPath; - const DrawerItem(this.title, this.icon, this.navigationPath); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(left: 30, top: 60), - child: Row( - children: [ - Icon(icon), - SizedBox( - width: 30, - ), - NavBarItem(title, navigationPath) - ], - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/navigation_drawer.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/navigation_drawer.dart deleted file mode 100644 index 79280c40..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/navigation_drawer.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navigation_drawer/drawer_item.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer_header.dart'; - -class NavigationDrawer extends StatelessWidget { - const NavigationDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 300, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(color: Colors.black12, blurRadius: 16), - ], - ), - child: Column( - children: [ - NavigationDrawerHeader(), - // BONUS: Combine the UI for this widget with the NavBarItem and make it responsive. - // The UI for the current DrawerItem shows when it's in mobile, else it shows the NavBarItem ui. - DrawerItem('Episodes', Icons.videocam, EpisodesRoute), - DrawerItem('About', Icons.help, AboutRoute), - ], - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/navigation_drawer_header.dart b/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/navigation_drawer_header.dart deleted file mode 100644 index 0b96e2af..00000000 --- a/034-flutter-web-part3-template-layouts/lib/widgets/navigation_drawer/navigation_drawer_header.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class NavigationDrawerHeader extends StatelessWidget { - const NavigationDrawerHeader({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 150, - color: primaryColor, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'SKILL UP NOW', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white), - ), - Text( - 'TAP HERE', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ); - } -} diff --git a/034-flutter-web-part3-template-layouts/pubspec.lock b/034-flutter-web-part3-template-layouts/pubspec.lock deleted file mode 100644 index 5f9f479f..00000000 --- a/034-flutter-web-part3-template-layouts/pubspec.lock +++ /dev/null @@ -1,160 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - responsive_builder: - dependency: "direct main" - description: - name: responsive_builder - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/034-flutter-web-part3-template-layouts/pubspec.yaml b/034-flutter-web-part3-template-layouts/pubspec.yaml deleted file mode 100644 index 5af9bd75..00000000 --- a/034-flutter-web-part3-template-layouts/pubspec.yaml +++ /dev/null @@ -1,75 +0,0 @@ -name: the_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - responsive_builder: ^0.2.0+2 - get_it: ^4.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/logo.png - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/034-flutter-web-part3-template-layouts/test/widget_test.dart b/034-flutter-web-part3-template-layouts/test/widget_test.dart deleted file mode 100644 index b9e0d165..00000000 --- a/034-flutter-web-part3-template-layouts/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:the_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/034-flutter-web-part3-template-layouts/web/index.html b/034-flutter-web-part3-template-layouts/web/index.html deleted file mode 100644 index b7d4703b..00000000 --- a/034-flutter-web-part3-template-layouts/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - the_basics - - - - - diff --git a/035-statemanagement-api-integration/00-starting/.firebaserc b/035-statemanagement-api-integration/00-starting/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/035-statemanagement-api-integration/00-starting/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/035-statemanagement-api-integration/00-starting/.gitignore b/035-statemanagement-api-integration/00-starting/.gitignore deleted file mode 100644 index 36a616eb..00000000 --- a/035-statemanagement-api-integration/00-starting/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/035-statemanagement-api-integration/00-starting/.metadata b/035-statemanagement-api-integration/00-starting/.metadata deleted file mode 100644 index c17efdcf..00000000 --- a/035-statemanagement-api-integration/00-starting/.metadata +++ /dev/null @@ -1,10 +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: 8e0799a657051bf540d98b8aecf9cfa1325f3f71 - channel: master - -project_type: app diff --git a/035-statemanagement-api-integration/00-starting/README.md b/035-statemanagement-api-integration/00-starting/README.md deleted file mode 100644 index e42c305e..00000000 --- a/035-statemanagement-api-integration/00-starting/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# the_basics - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/035-statemanagement-api-integration/00-starting/assets/fonts/OpenSans-ExtraBold.ttf b/035-statemanagement-api-integration/00-starting/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/035-statemanagement-api-integration/00-starting/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/035-statemanagement-api-integration/00-starting/assets/fonts/OpenSans-Regular.ttf b/035-statemanagement-api-integration/00-starting/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/035-statemanagement-api-integration/00-starting/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/035-statemanagement-api-integration/00-starting/assets/logo.png b/035-statemanagement-api-integration/00-starting/assets/logo.png deleted file mode 100644 index bcd4c4b9..00000000 Binary files a/035-statemanagement-api-integration/00-starting/assets/logo.png and /dev/null differ diff --git a/035-statemanagement-api-integration/00-starting/firebase.json b/035-statemanagement-api-integration/00-starting/firebase.json deleted file mode 100644 index 66037326..00000000 --- a/035-statemanagement-api-integration/00-starting/firebase.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosting": { - "public": "build/web", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/constants/app_colors.dart b/035-statemanagement-api-integration/00-starting/lib/constants/app_colors.dart deleted file mode 100644 index 4524aca0..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/constants/app_colors.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color primaryColor = Color.fromARGB(255, 31, 229, 146); \ No newline at end of file diff --git a/035-statemanagement-api-integration/00-starting/lib/datamodels/episode_item_model.dart b/035-statemanagement-api-integration/00-starting/lib/datamodels/episode_item_model.dart deleted file mode 100644 index 397adab3..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/datamodels/episode_item_model.dart +++ /dev/null @@ -1,16 +0,0 @@ -class EpisodeItemModel { - final String title; - final double duration; - final String imageUrl; - - EpisodeItemModel({ - this.title, - this.duration, - this.imageUrl, - }); - - EpisodeItemModel.fromJson(Map map) - : title = map['title'], - duration = map['duration'], - imageUrl = map['imageUrl']; -} diff --git a/035-statemanagement-api-integration/00-starting/lib/datamodels/navbar_item_model.dart b/035-statemanagement-api-integration/00-starting/lib/datamodels/navbar_item_model.dart deleted file mode 100644 index c3b4d632..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/datamodels/navbar_item_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class NavBarItemModel { - final String title; - final String navigationPath; - final IconData iconData; - - NavBarItemModel({ - this.title, - this.navigationPath, - this.iconData, - }); -} diff --git a/035-statemanagement-api-integration/00-starting/lib/datamodels/season_details_model.dart b/035-statemanagement-api-integration/00-starting/lib/datamodels/season_details_model.dart deleted file mode 100644 index 5bb623fc..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/datamodels/season_details_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class SeasonDetailsModel { - final String title; - final String description; - - SeasonDetailsModel({ - @required this.title, - @required this.description, - }); -} diff --git a/035-statemanagement-api-integration/00-starting/lib/locator.dart b/035-statemanagement-api-integration/00-starting/lib/locator.dart deleted file mode 100644 index f68ca6b6..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/locator.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:the_basics/services/navigation_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); -} \ No newline at end of file diff --git a/035-statemanagement-api-integration/00-starting/lib/main.dart b/035-statemanagement-api-integration/00-starting/lib/main.dart deleted file mode 100644 index 135075f6..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/main.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/views/layout_template/layout_template.dart'; - -import 'locator.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - textTheme: Theme.of(context).textTheme.apply(fontFamily: 'Open Sans'), - ), - home: LayoutTemplate(), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/routing/route_names.dart b/035-statemanagement-api-integration/00-starting/lib/routing/route_names.dart deleted file mode 100644 index c8aeef50..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/routing/route_names.dart +++ /dev/null @@ -1,3 +0,0 @@ -const String HomeRoute = 'home'; -const String AboutRoute = 'about'; -const String EpisodesRoute = 'episodes'; diff --git a/035-statemanagement-api-integration/00-starting/lib/routing/router.dart b/035-statemanagement-api-integration/00-starting/lib/routing/router.dart deleted file mode 100644 index d013f18d..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/routing/router.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/views/about/about_view.dart'; -import 'package:the_basics/views/episodes/episodes_view.dart'; -import 'package:the_basics/views/home/home_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case HomeRoute: - return _getPageRoute(HomeView(), settings); - case AboutRoute: - return _getPageRoute(AboutView(), settings); - case EpisodesRoute: - return _getPageRoute(EpisodesView(), settings); - default: - return _getPageRoute(HomeView(), settings); - } -} - -PageRoute _getPageRoute(Widget child, RouteSettings settings) { - return _FadeRoute(child: child, routeName: settings.name); -} - -class _FadeRoute extends PageRouteBuilder { - final Widget child; - final String routeName; - _FadeRoute({this.child, this.routeName}) - : super( - settings: RouteSettings(name: routeName), - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) => - child, - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => - FadeTransition( - opacity: animation, - child: child, - ), - ); -} diff --git a/035-statemanagement-api-integration/00-starting/lib/services/navigation_service.dart b/035-statemanagement-api-integration/00-starting/lib/services/navigation_service.dart deleted file mode 100644 index d4a51a00..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/services/navigation_service.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - final GlobalKey navigatorKey = GlobalKey(); - - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); - } - - void goBack() { - return navigatorKey.currentState.pop(); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/styles/text_styles.dart b/035-statemanagement-api-integration/00-starting/lib/styles/text_styles.dart deleted file mode 100644 index de84920b..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/styles/text_styles.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -/// Returns the style for a page title based on the [deviceScreenType] passed in. -TextStyle titleTextStyle(DeviceScreenType deviceScreenType) { - double titleSize = deviceScreenType == DeviceScreenType.mobile ? 50 : 80; - return TextStyle( - fontWeight: FontWeight.w800, height: 0.9, fontSize: titleSize); -} - -/// Return the style for description text on a page based on the [deviceScreenType] passed in. -TextStyle descriptionTextStyle(DeviceScreenType deviceScreenType) { - double descriptionSize = - deviceScreenType == DeviceScreenType.mobile ? 16 : 21; - - return TextStyle( - fontSize: descriptionSize, - height: 1.7, - ); -} diff --git a/035-statemanagement-api-integration/00-starting/lib/views/about/about_view.dart b/035-statemanagement-api-integration/00-starting/lib/views/about/about_view.dart deleted file mode 100644 index 34741b6f..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/views/about/about_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class AboutView extends StatelessWidget { - const AboutView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.red, - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/views/episodes/episodes_view.dart b/035-statemanagement-api-integration/00-starting/lib/views/episodes/episodes_view.dart deleted file mode 100644 index 10f6bd40..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/views/episodes/episodes_view.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/widgets/episodes_list/episodes_list.dart'; -import 'package:the_basics/widgets/season_details/season_details.dart'; - -class EpisodesView extends StatelessWidget { - const EpisodesView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - SizedBox( - height: 100, - ), - SeasonDetails( - details: SeasonDetailsModel( - title: 'SEASON 1', - description: - 'This season covers the absolute basics of Flutter Web Dev to get us up and running with a basic web app.', - ), - ), - SizedBox( - height: 50, - ), - EpisodesList(), - ], - )); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/views/home/home_content_desktop.dart b/035-statemanagement-api-integration/00-starting/lib/views/home/home_content_desktop.dart deleted file mode 100644 index 4fab7a21..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/views/home/home_content_desktop.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentDesktop extends StatelessWidget { - const HomeContentDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Row( - children: [ - CourseDetails(), - Expanded( - child: Center( - child: CallToAction('Join Course'), - ), - ) - ], - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/views/home/home_content_mobile.dart b/035-statemanagement-api-integration/00-starting/lib/views/home/home_content_mobile.dart deleted file mode 100644 index 028c8d38..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/views/home/home_content_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentMobile extends StatelessWidget { - const HomeContentMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CourseDetails(), - SizedBox( - height: 100, - ), - CallToAction('Join Course'), - ], - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/views/home/home_view.dart b/035-statemanagement-api-integration/00-starting/lib/views/home/home_view.dart deleted file mode 100644 index a138243d..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/views/home/home_view.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/views/home/home_content_desktop.dart'; -import 'package:the_basics/views/home/home_content_mobile.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: HomeContentMobile(), - desktop: HomeContentDesktop(), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/views/layout_template/layout_template.dart b/035-statemanagement-api-integration/00-starting/lib/views/layout_template/layout_template.dart deleted file mode 100644 index b6d5030d..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/views/layout_template/layout_template.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/routing/router.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/centered_view/centered_view.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer.dart'; - -class LayoutTemplate extends StatelessWidget { - const LayoutTemplate({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Scaffold( - drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? NavigationDrawer() - : null, - backgroundColor: Colors.white, - body: CenteredView( - child: Column( - children: [ - NavigationBar(), - Expanded( - child: Navigator( - key: locator().navigatorKey, - onGenerateRoute: generateRoute, - initialRoute: HomeRoute, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action.dart deleted file mode 100644 index d5c72e8a..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_mobile.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_tablet_desktop.dart'; - -class CallToAction extends StatelessWidget { - final String title; - CallToAction(this.title); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: CallToActionMobile(title), - tablet: CallToActionTabletDesktop(title), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action_mobile.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action_mobile.dart deleted file mode 100644 index d2455218..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action_mobile.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionMobile extends StatelessWidget { - final String title; - const CallToActionMobile(this.title); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - alignment: Alignment.center, - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart deleted file mode 100644 index 0ea18c80..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionTabletDesktop extends StatelessWidget { - final String title; - const CallToActionTabletDesktop(this.title); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15), - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/centered_view/centered_view.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/centered_view/centered_view.dart deleted file mode 100644 index 1aed138b..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/centered_view/centered_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class CenteredView extends StatelessWidget { - final Widget child; - const CenteredView({Key key, this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 60), - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 1200), - child: child, - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/course_details/course_details.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/course_details/course_details.dart deleted file mode 100644 index 299ed635..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/course_details/course_details.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class CourseDetails extends StatelessWidget { - const CourseDetails({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - var textAlignment = - sizingInformation.deviceScreenType == DeviceScreenType.desktop - ? TextAlign.left - : TextAlign.center; - - return Container( - width: 600, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'FLUTTER WEB.\nTHE BASICS', - style: titleTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ), - SizedBox( - height: 30, - ), - Text( - 'In this course we will go over the basics of using Flutter Web for website development. Topics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.', - style: descriptionTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ) - ], - ), - ); - }, - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/episodes_list/episode_item.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/episodes_list/episode_item.dart deleted file mode 100644 index 4f8319ec..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/episodes_list/episode_item.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; - -class EpisodeItem extends StatelessWidget { - final EpisodeItemModel model; - const EpisodeItem({ - Key key, - this.model, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Card( - color: Colors.white, - elevation: 2, - child: SizedBox( - width: 360, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 180, - child: Image.network(model.imageUrl, fit: BoxFit.cover,), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15.0, - vertical: 20, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - model.title, - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 14, - ), - softWrap: true, - ), - Text( - '${model.duration} minutes', - style: TextStyle(fontSize: 10), - ) - ], - ), - ), - ], - ), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/episodes_list/episodes_list.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/episodes_list/episodes_list.dart deleted file mode 100644 index ef477007..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/episodes_list/episodes_list.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; - -import 'episode_item.dart'; - -class EpisodesList extends StatelessWidget { - final episodes = [ - EpisodeItemModel( - title: 'Setup, Build and Deploy', - duration: 14.07, - imageUrl: - 'https://www.filledstacks.com/assets/static/32.81b85c1.ebb7a1a.jpg', - ), - EpisodeItemModel( - title: 'Adding a Responsive UI', - duration: 18.54, - imageUrl: - 'https://www.filledstacks.com/assets/static/033.81b85c1.ebdf16d.jpg'), - EpisodeItemModel( - title: 'Layout Templates', - duration: 14.55, - imageUrl: - 'https://www.filledstacks.com/assets/static/034.81b85c1.52d0785.jpg'), - EpisodeItemModel( - title: 'State Management and Api integration', - duration: 14.55, - imageUrl: - 'https://www.filledstacks.com/assets/static/034.81b85c1.52d0785.jpg'), - ]; - - @override - Widget build(BuildContext context) { - return Wrap( - spacing: 30, - runSpacing: 30, - children: [ - ...episodes.map( - (episode) => EpisodeItem(model: episode), - ) - ], - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item.dart deleted file mode 100644 index c6f3b91c..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_desktop.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_mobile.dart'; - -class NavBarItem extends StatelessWidget { - final String title; - final String navigationPath; - final IconData icon; - const NavBarItem(this.title, this.navigationPath, {this.icon}); - - @override - Widget build(BuildContext context) { - var model = NavBarItemModel( - title: title, - navigationPath: navigationPath, - iconData: icon, - ); - return GestureDetector( - onTap: () { - // DON'T EVER USE A SERVICE DIRECTLY IN THE UI TO CHANGE ANY KIND OF STATE - // SERVICES SHOULD ONLY BE USED FROM A VIEWMODEL - locator().navigateTo(navigationPath); - }, - child: ScreenTypeLayout( - tablet: NavBarItemTabletDesktop( - model: model, - ), - mobile: NavBarItemMobile( - model: model, - ), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item_desktop.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item_desktop.dart deleted file mode 100644 index 3d35442c..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item_desktop.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemTabletDesktop extends StatelessWidget { - final NavBarItemModel model; - NavBarItemTabletDesktop({this.model}); - - @override - Widget build( - BuildContext context, - ) { - return Text( - model.title, - style: TextStyle(fontSize: 18), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item_mobile.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item_mobile.dart deleted file mode 100644 index 6b25b3af..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navbar_item/navbar_item_mobile.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemMobile extends StatelessWidget { - final NavBarItemModel model; - NavBarItemMobile({this.model}); - - @override - Widget build(BuildContext context) { - return Padding( - padding: const EdgeInsets.only(left: 30, top: 60), - child: Row( - children: [ - Icon(model.iconData), - SizedBox( - width: 30, - ), - Text( - model.title, - style: TextStyle(fontSize: 18), - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navbar_logo.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navbar_logo.dart deleted file mode 100644 index 483fe20f..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navbar_logo.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavBarLogo extends StatelessWidget { - const NavBarLogo({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 80, - width: 150, - child: Image.asset('assets/logo.png'), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar.dart deleted file mode 100644 index a09d1e34..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_tablet_desktop.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_mobile.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class NavigationBar extends StatelessWidget { - const NavigationBar({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: NavigationBarMobile(), - tablet: NavigationBarTabletDesktop(), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar_mobile.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar_mobile.dart deleted file mode 100644 index 387f852c..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_logo.dart'; - -class NavigationBarMobile extends StatelessWidget { - const NavigationBarMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 80, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: Icon(Icons.menu), - onPressed: () {}, - ), - NavBarLogo() - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart deleted file mode 100644 index 6f622c31..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; - -import 'navbar_logo.dart'; - -class NavigationBarTabletDesktop extends StatelessWidget { - const NavigationBarTabletDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - NavBarLogo(), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - NavBarItem('Episodes', EpisodesRoute), - SizedBox( - width: 60, - ), - NavBarItem('About', AboutRoute), - ], - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_drawer/navigation_drawer.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_drawer/navigation_drawer.dart deleted file mode 100644 index 257d4153..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_drawer/navigation_drawer.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer_header.dart'; - -class NavigationDrawer extends StatelessWidget { - const NavigationDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 300, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(color: Colors.black12, blurRadius: 16), - ], - ), - child: Column( - children: [ - NavigationDrawerHeader(), - // BONUS: Combine the UI for this widget with the NavBarItem and make it responsive. - // The UI for the current DrawerItem shows when it's in mobile, else it shows the NavBarItem ui. - NavBarItem( - 'Episodes', - EpisodesRoute, - icon: Icons.videocam, - ), - NavBarItem( - 'About', - AboutRoute, - icon: Icons.help, - ), - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_drawer/navigation_drawer_header.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_drawer/navigation_drawer_header.dart deleted file mode 100644 index 0b96e2af..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/navigation_drawer/navigation_drawer_header.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class NavigationDrawerHeader extends StatelessWidget { - const NavigationDrawerHeader({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 150, - color: primaryColor, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'SKILL UP NOW', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white), - ), - Text( - 'TAP HERE', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details.dart deleted file mode 100644 index 8576fa6b..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/widgets/season_details/season_details_desktop.dart'; -import 'package:the_basics/widgets/season_details/season_details_mobile.dart'; - -class SeasonDetails extends StatelessWidget { - final SeasonDetailsModel details; - const SeasonDetails({Key key, this.details}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - desktop: SeasonDetailsDesktop(details: details), - mobile: SeasonDetailsMobile(details: details), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details_desktop.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details_desktop.dart deleted file mode 100644 index ac0cd0a2..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details_desktop.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsDesktop extends StatelessWidget { - final SeasonDetailsModel details; - const SeasonDetailsDesktop({Key key, this.details}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - width: 50, - ), - Expanded( - child: Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details_mobile.dart b/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details_mobile.dart deleted file mode 100644 index 459ef6f4..00000000 --- a/035-statemanagement-api-integration/00-starting/lib/widgets/season_details/season_details_mobile.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsMobile extends StatelessWidget { - final SeasonDetailsModel details; - const SeasonDetailsMobile({Key key, this.details}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Column( - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - height: 50, - ), - Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/00-starting/pubspec.lock b/035-statemanagement-api-integration/00-starting/pubspec.lock deleted file mode 100644 index bc387118..00000000 --- a/035-statemanagement-api-integration/00-starting/pubspec.lock +++ /dev/null @@ -1,160 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - responsive_builder: - dependency: "direct main" - description: - name: responsive_builder - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" diff --git a/035-statemanagement-api-integration/00-starting/pubspec.yaml b/035-statemanagement-api-integration/00-starting/pubspec.yaml deleted file mode 100644 index 7508cc7c..00000000 --- a/035-statemanagement-api-integration/00-starting/pubspec.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: the_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - responsive_builder: ^0.2.0+2 - get_it: - # provider_architecture: - # path: ../provider_architecture - # provider: ^3.1.0 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/logo.png - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/035-statemanagement-api-integration/00-starting/test/widget_test.dart b/035-statemanagement-api-integration/00-starting/test/widget_test.dart deleted file mode 100644 index b9e0d165..00000000 --- a/035-statemanagement-api-integration/00-starting/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:the_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/035-statemanagement-api-integration/00-starting/web/index.html b/035-statemanagement-api-integration/00-starting/web/index.html deleted file mode 100644 index b7d4703b..00000000 --- a/035-statemanagement-api-integration/00-starting/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - the_basics - - - - - diff --git a/035-statemanagement-api-integration/01-final/.firebaserc b/035-statemanagement-api-integration/01-final/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/035-statemanagement-api-integration/01-final/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/035-statemanagement-api-integration/01-final/.gitignore b/035-statemanagement-api-integration/01-final/.gitignore deleted file mode 100644 index 36a616eb..00000000 --- a/035-statemanagement-api-integration/01-final/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/035-statemanagement-api-integration/01-final/.metadata b/035-statemanagement-api-integration/01-final/.metadata deleted file mode 100644 index c17efdcf..00000000 --- a/035-statemanagement-api-integration/01-final/.metadata +++ /dev/null @@ -1,10 +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: 8e0799a657051bf540d98b8aecf9cfa1325f3f71 - channel: master - -project_type: app diff --git a/035-statemanagement-api-integration/01-final/README.md b/035-statemanagement-api-integration/01-final/README.md deleted file mode 100644 index e42c305e..00000000 --- a/035-statemanagement-api-integration/01-final/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# the_basics - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/035-statemanagement-api-integration/01-final/assets/fonts/OpenSans-ExtraBold.ttf b/035-statemanagement-api-integration/01-final/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/035-statemanagement-api-integration/01-final/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/035-statemanagement-api-integration/01-final/assets/fonts/OpenSans-Regular.ttf b/035-statemanagement-api-integration/01-final/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/035-statemanagement-api-integration/01-final/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/035-statemanagement-api-integration/01-final/assets/logo.png b/035-statemanagement-api-integration/01-final/assets/logo.png deleted file mode 100644 index bcd4c4b9..00000000 Binary files a/035-statemanagement-api-integration/01-final/assets/logo.png and /dev/null differ diff --git a/035-statemanagement-api-integration/01-final/firebase.json b/035-statemanagement-api-integration/01-final/firebase.json deleted file mode 100644 index 66037326..00000000 --- a/035-statemanagement-api-integration/01-final/firebase.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosting": { - "public": "build/web", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/constants/app_colors.dart b/035-statemanagement-api-integration/01-final/lib/constants/app_colors.dart deleted file mode 100644 index 4524aca0..00000000 --- a/035-statemanagement-api-integration/01-final/lib/constants/app_colors.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color primaryColor = Color.fromARGB(255, 31, 229, 146); \ No newline at end of file diff --git a/035-statemanagement-api-integration/01-final/lib/datamodels/episode_item_model.dart b/035-statemanagement-api-integration/01-final/lib/datamodels/episode_item_model.dart deleted file mode 100644 index 397adab3..00000000 --- a/035-statemanagement-api-integration/01-final/lib/datamodels/episode_item_model.dart +++ /dev/null @@ -1,16 +0,0 @@ -class EpisodeItemModel { - final String title; - final double duration; - final String imageUrl; - - EpisodeItemModel({ - this.title, - this.duration, - this.imageUrl, - }); - - EpisodeItemModel.fromJson(Map map) - : title = map['title'], - duration = map['duration'], - imageUrl = map['imageUrl']; -} diff --git a/035-statemanagement-api-integration/01-final/lib/datamodels/navbar_item_model.dart b/035-statemanagement-api-integration/01-final/lib/datamodels/navbar_item_model.dart deleted file mode 100644 index c3b4d632..00000000 --- a/035-statemanagement-api-integration/01-final/lib/datamodels/navbar_item_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class NavBarItemModel { - final String title; - final String navigationPath; - final IconData iconData; - - NavBarItemModel({ - this.title, - this.navigationPath, - this.iconData, - }); -} diff --git a/035-statemanagement-api-integration/01-final/lib/datamodels/season_details_model.dart b/035-statemanagement-api-integration/01-final/lib/datamodels/season_details_model.dart deleted file mode 100644 index 5bb623fc..00000000 --- a/035-statemanagement-api-integration/01-final/lib/datamodels/season_details_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class SeasonDetailsModel { - final String title; - final String description; - - SeasonDetailsModel({ - @required this.title, - @required this.description, - }); -} diff --git a/035-statemanagement-api-integration/01-final/lib/locator.dart b/035-statemanagement-api-integration/01-final/lib/locator.dart deleted file mode 100644 index a0c940fc..00000000 --- a/035-statemanagement-api-integration/01-final/lib/locator.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:the_basics/services/api.dart'; -import 'package:the_basics/services/navigation_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => Api()); -} \ No newline at end of file diff --git a/035-statemanagement-api-integration/01-final/lib/main.dart b/035-statemanagement-api-integration/01-final/lib/main.dart deleted file mode 100644 index 135075f6..00000000 --- a/035-statemanagement-api-integration/01-final/lib/main.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/views/layout_template/layout_template.dart'; - -import 'locator.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - textTheme: Theme.of(context).textTheme.apply(fontFamily: 'Open Sans'), - ), - home: LayoutTemplate(), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/routing/route_names.dart b/035-statemanagement-api-integration/01-final/lib/routing/route_names.dart deleted file mode 100644 index c8aeef50..00000000 --- a/035-statemanagement-api-integration/01-final/lib/routing/route_names.dart +++ /dev/null @@ -1,3 +0,0 @@ -const String HomeRoute = 'home'; -const String AboutRoute = 'about'; -const String EpisodesRoute = 'episodes'; diff --git a/035-statemanagement-api-integration/01-final/lib/routing/router.dart b/035-statemanagement-api-integration/01-final/lib/routing/router.dart deleted file mode 100644 index d013f18d..00000000 --- a/035-statemanagement-api-integration/01-final/lib/routing/router.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/views/about/about_view.dart'; -import 'package:the_basics/views/episodes/episodes_view.dart'; -import 'package:the_basics/views/home/home_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case HomeRoute: - return _getPageRoute(HomeView(), settings); - case AboutRoute: - return _getPageRoute(AboutView(), settings); - case EpisodesRoute: - return _getPageRoute(EpisodesView(), settings); - default: - return _getPageRoute(HomeView(), settings); - } -} - -PageRoute _getPageRoute(Widget child, RouteSettings settings) { - return _FadeRoute(child: child, routeName: settings.name); -} - -class _FadeRoute extends PageRouteBuilder { - final Widget child; - final String routeName; - _FadeRoute({this.child, this.routeName}) - : super( - settings: RouteSettings(name: routeName), - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) => - child, - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => - FadeTransition( - opacity: animation, - child: child, - ), - ); -} diff --git a/035-statemanagement-api-integration/01-final/lib/services/api.dart b/035-statemanagement-api-integration/01-final/lib/services/api.dart deleted file mode 100644 index ff9b4094..00000000 --- a/035-statemanagement-api-integration/01-final/lib/services/api.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:http/http.dart' as http; -import 'dart:convert'; - -import 'package:the_basics/datamodels/episode_item_model.dart'; - -class Api { - static const String _apiEndpoint = - 'https://us-central1-thebasics-2f123.cloudfunctions.net/thebasics'; - - Future getEpisodes() async { - var response = await http.get('$_apiEndpoint/courseEpisodes'); - - if (response.statusCode == 200) { - var episodes = (json.decode(response.body) as List) - .map((episode) => EpisodeItemModel.fromJson(episode)) - .toList(); - return episodes; - } - - // something wrong happened - return 'Could not fetch the episodes at this time'; - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/services/navigation_service.dart b/035-statemanagement-api-integration/01-final/lib/services/navigation_service.dart deleted file mode 100644 index d4a51a00..00000000 --- a/035-statemanagement-api-integration/01-final/lib/services/navigation_service.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - final GlobalKey navigatorKey = GlobalKey(); - - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); - } - - void goBack() { - return navigatorKey.currentState.pop(); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/styles/text_styles.dart b/035-statemanagement-api-integration/01-final/lib/styles/text_styles.dart deleted file mode 100644 index de84920b..00000000 --- a/035-statemanagement-api-integration/01-final/lib/styles/text_styles.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -/// Returns the style for a page title based on the [deviceScreenType] passed in. -TextStyle titleTextStyle(DeviceScreenType deviceScreenType) { - double titleSize = deviceScreenType == DeviceScreenType.mobile ? 50 : 80; - return TextStyle( - fontWeight: FontWeight.w800, height: 0.9, fontSize: titleSize); -} - -/// Return the style for description text on a page based on the [deviceScreenType] passed in. -TextStyle descriptionTextStyle(DeviceScreenType deviceScreenType) { - double descriptionSize = - deviceScreenType == DeviceScreenType.mobile ? 16 : 21; - - return TextStyle( - fontSize: descriptionSize, - height: 1.7, - ); -} diff --git a/035-statemanagement-api-integration/01-final/lib/viewmodels/episodes_view_model.dart b/035-statemanagement-api-integration/01-final/lib/viewmodels/episodes_view_model.dart deleted file mode 100644 index e7a17521..00000000 --- a/035-statemanagement-api-integration/01-final/lib/viewmodels/episodes_view_model.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/api.dart'; - -class EpisodesViewModel extends ChangeNotifier { - final _api = locator(); - - List _episodes; - List get episodes => _episodes; - - Future getEpisodes() async { - var episodeResults = await _api.getEpisodes(); - - if (episodeResults is String) { - // show error - } else { - _episodes = episodeResults; - } - - notifyListeners(); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/views/about/about_view.dart b/035-statemanagement-api-integration/01-final/lib/views/about/about_view.dart deleted file mode 100644 index 34741b6f..00000000 --- a/035-statemanagement-api-integration/01-final/lib/views/about/about_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class AboutView extends StatelessWidget { - const AboutView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.red, - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/views/episodes/episodes_view.dart b/035-statemanagement-api-integration/01-final/lib/views/episodes/episodes_view.dart deleted file mode 100644 index 5bed4225..00000000 --- a/035-statemanagement-api-integration/01-final/lib/views/episodes/episodes_view.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/viewmodels/episodes_view_model.dart'; -import 'package:the_basics/widgets/episodes_list/episodes_list.dart'; -import 'package:the_basics/widgets/season_details/season_details.dart'; - -class EpisodesView extends StatelessWidget { - const EpisodesView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => EpisodesViewModel(), - onModelReady: (model) => model.getEpisodes(), - builder: (context, model, child) => SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - SizedBox( - height: 100, - ), - SeasonDetails( - details: SeasonDetailsModel( - title: 'SEASON 1', - description: - 'This season covers the absolute basics of Flutter Web Dev to get us up and running with a basic web app.', - ), - ), - SizedBox( - height: 50, - ), - model.episodes == null - ? CircularProgressIndicator() - : EpisodesList(episodes: model.episodes), - ], - )), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/views/home/home_content_desktop.dart b/035-statemanagement-api-integration/01-final/lib/views/home/home_content_desktop.dart deleted file mode 100644 index 4fab7a21..00000000 --- a/035-statemanagement-api-integration/01-final/lib/views/home/home_content_desktop.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentDesktop extends StatelessWidget { - const HomeContentDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Row( - children: [ - CourseDetails(), - Expanded( - child: Center( - child: CallToAction('Join Course'), - ), - ) - ], - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/views/home/home_content_mobile.dart b/035-statemanagement-api-integration/01-final/lib/views/home/home_content_mobile.dart deleted file mode 100644 index 028c8d38..00000000 --- a/035-statemanagement-api-integration/01-final/lib/views/home/home_content_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentMobile extends StatelessWidget { - const HomeContentMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CourseDetails(), - SizedBox( - height: 100, - ), - CallToAction('Join Course'), - ], - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/views/home/home_view.dart b/035-statemanagement-api-integration/01-final/lib/views/home/home_view.dart deleted file mode 100644 index a138243d..00000000 --- a/035-statemanagement-api-integration/01-final/lib/views/home/home_view.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/views/home/home_content_desktop.dart'; -import 'package:the_basics/views/home/home_content_mobile.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: HomeContentMobile(), - desktop: HomeContentDesktop(), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/views/layout_template/layout_template.dart b/035-statemanagement-api-integration/01-final/lib/views/layout_template/layout_template.dart deleted file mode 100644 index b6d5030d..00000000 --- a/035-statemanagement-api-integration/01-final/lib/views/layout_template/layout_template.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/routing/router.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/centered_view/centered_view.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer.dart'; - -class LayoutTemplate extends StatelessWidget { - const LayoutTemplate({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Scaffold( - drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? NavigationDrawer() - : null, - backgroundColor: Colors.white, - body: CenteredView( - child: Column( - children: [ - NavigationBar(), - Expanded( - child: Navigator( - key: locator().navigatorKey, - onGenerateRoute: generateRoute, - initialRoute: HomeRoute, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action.dart b/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action.dart deleted file mode 100644 index d5c72e8a..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_mobile.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_tablet_desktop.dart'; - -class CallToAction extends StatelessWidget { - final String title; - CallToAction(this.title); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: CallToActionMobile(title), - tablet: CallToActionTabletDesktop(title), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action_mobile.dart b/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action_mobile.dart deleted file mode 100644 index d2455218..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action_mobile.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionMobile extends StatelessWidget { - final String title; - const CallToActionMobile(this.title); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - alignment: Alignment.center, - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart b/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart deleted file mode 100644 index 0ea18c80..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionTabletDesktop extends StatelessWidget { - final String title; - const CallToActionTabletDesktop(this.title); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15), - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/centered_view/centered_view.dart b/035-statemanagement-api-integration/01-final/lib/widgets/centered_view/centered_view.dart deleted file mode 100644 index 1aed138b..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/centered_view/centered_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class CenteredView extends StatelessWidget { - final Widget child; - const CenteredView({Key key, this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 60), - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 1200), - child: child, - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/course_details/course_details.dart b/035-statemanagement-api-integration/01-final/lib/widgets/course_details/course_details.dart deleted file mode 100644 index 299ed635..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/course_details/course_details.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class CourseDetails extends StatelessWidget { - const CourseDetails({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - var textAlignment = - sizingInformation.deviceScreenType == DeviceScreenType.desktop - ? TextAlign.left - : TextAlign.center; - - return Container( - width: 600, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'FLUTTER WEB.\nTHE BASICS', - style: titleTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ), - SizedBox( - height: 30, - ), - Text( - 'In this course we will go over the basics of using Flutter Web for website development. Topics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.', - style: descriptionTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ) - ], - ), - ); - }, - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/episodes_list/episode_item.dart b/035-statemanagement-api-integration/01-final/lib/widgets/episodes_list/episode_item.dart deleted file mode 100644 index 4f8319ec..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/episodes_list/episode_item.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; - -class EpisodeItem extends StatelessWidget { - final EpisodeItemModel model; - const EpisodeItem({ - Key key, - this.model, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Card( - color: Colors.white, - elevation: 2, - child: SizedBox( - width: 360, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 180, - child: Image.network(model.imageUrl, fit: BoxFit.cover,), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15.0, - vertical: 20, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - model.title, - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 14, - ), - softWrap: true, - ), - Text( - '${model.duration} minutes', - style: TextStyle(fontSize: 10), - ) - ], - ), - ), - ], - ), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/episodes_list/episodes_list.dart b/035-statemanagement-api-integration/01-final/lib/widgets/episodes_list/episodes_list.dart deleted file mode 100644 index b7d92041..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/episodes_list/episodes_list.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; - -import 'episode_item.dart'; - -class EpisodesList extends StatelessWidget { - final List episodes; - EpisodesList({this.episodes}); - - @override - Widget build(BuildContext context) { - return Wrap( - spacing: 30, - runSpacing: 30, - children: [ - ...episodes.map( - (episode) => EpisodeItem(model: episode), - ) - ], - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item.dart deleted file mode 100644 index 11dc08b8..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_desktop.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_mobile.dart'; - -class NavBarItem extends StatelessWidget { - final String title; - final String navigationPath; - final IconData icon; - const NavBarItem(this.title, this.navigationPath, {this.icon}); - - @override - Widget build(BuildContext context) { - var model = NavBarItemModel( - title: title, - navigationPath: navigationPath, - iconData: icon, - ); - return GestureDetector( - onTap: () { - // DON'T EVER USE A SERVICE DIRECTLY IN THE UI TO CHANGE ANY KIND OF STATE - // SERVICES SHOULD ONLY BE USED FROM A VIEWMODEL - locator().navigateTo(navigationPath); - }, - child: Provider.value( - value: model, - child: ScreenTypeLayout( - tablet: NavBarItemTabletDesktop(), - mobile: NavBarItemMobile(), - ), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item_desktop.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item_desktop.dart deleted file mode 100644 index 49dd9b81..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item_desktop.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemTabletDesktop extends ViewModelWidget { - @override - Widget build(BuildContext context, NavBarItemModel model) { - return Text( - model.title, - style: TextStyle(fontSize: 18), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item_mobile.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item_mobile.dart deleted file mode 100644 index beee7c38..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navbar_item/navbar_item_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemMobile extends ViewModelWidget { - @override - Widget build(BuildContext context, NavBarItemModel model) { - return Padding( - padding: const EdgeInsets.only(left: 30, top: 60), - child: Row( - children: [ - Icon(model.iconData), - SizedBox( - width: 30, - ), - Text( - model.title, - style: TextStyle(fontSize: 18), - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navbar_logo.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navbar_logo.dart deleted file mode 100644 index 483fe20f..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navbar_logo.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavBarLogo extends StatelessWidget { - const NavBarLogo({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 80, - width: 150, - child: Image.asset('assets/logo.png'), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar.dart deleted file mode 100644 index a09d1e34..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_tablet_desktop.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_mobile.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class NavigationBar extends StatelessWidget { - const NavigationBar({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: NavigationBarMobile(), - tablet: NavigationBarTabletDesktop(), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar_mobile.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar_mobile.dart deleted file mode 100644 index 387f852c..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_logo.dart'; - -class NavigationBarMobile extends StatelessWidget { - const NavigationBarMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 80, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: Icon(Icons.menu), - onPressed: () {}, - ), - NavBarLogo() - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart deleted file mode 100644 index 6f622c31..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; - -import 'navbar_logo.dart'; - -class NavigationBarTabletDesktop extends StatelessWidget { - const NavigationBarTabletDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - NavBarLogo(), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - NavBarItem('Episodes', EpisodesRoute), - SizedBox( - width: 60, - ), - NavBarItem('About', AboutRoute), - ], - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_drawer/navigation_drawer.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navigation_drawer/navigation_drawer.dart deleted file mode 100644 index 257d4153..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_drawer/navigation_drawer.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer_header.dart'; - -class NavigationDrawer extends StatelessWidget { - const NavigationDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 300, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(color: Colors.black12, blurRadius: 16), - ], - ), - child: Column( - children: [ - NavigationDrawerHeader(), - // BONUS: Combine the UI for this widget with the NavBarItem and make it responsive. - // The UI for the current DrawerItem shows when it's in mobile, else it shows the NavBarItem ui. - NavBarItem( - 'Episodes', - EpisodesRoute, - icon: Icons.videocam, - ), - NavBarItem( - 'About', - AboutRoute, - icon: Icons.help, - ), - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_drawer/navigation_drawer_header.dart b/035-statemanagement-api-integration/01-final/lib/widgets/navigation_drawer/navigation_drawer_header.dart deleted file mode 100644 index 0b96e2af..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/navigation_drawer/navigation_drawer_header.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class NavigationDrawerHeader extends StatelessWidget { - const NavigationDrawerHeader({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 150, - color: primaryColor, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'SKILL UP NOW', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white), - ), - Text( - 'TAP HERE', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details.dart b/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details.dart deleted file mode 100644 index 7b4b5a0f..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/widgets/season_details/season_details_desktop.dart'; -import 'package:the_basics/widgets/season_details/season_details_mobile.dart'; - -class SeasonDetails extends StatelessWidget { - final SeasonDetailsModel details; - const SeasonDetails({Key key, this.details}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Provider.value( - value: details, - child: ScreenTypeLayout( - desktop: SeasonDetailsDesktop(), - mobile: SeasonDetailsMobile(), - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details_desktop.dart b/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details_desktop.dart deleted file mode 100644 index b98619a8..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsDesktop extends ViewModelWidget { - @override - Widget build(BuildContext context, SeasonDetailsModel details) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - width: 50, - ), - Expanded( - child: Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ) - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details_mobile.dart b/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details_mobile.dart deleted file mode 100644 index f6d5ec3d..00000000 --- a/035-statemanagement-api-integration/01-final/lib/widgets/season_details/season_details_mobile.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsMobile extends ViewModelWidget { - @override - Widget build(BuildContext context, SeasonDetailsModel details) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Column( - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - height: 50, - ), - Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ], - ), - ); - } -} diff --git a/035-statemanagement-api-integration/01-final/pubspec.lock b/035-statemanagement-api-integration/01-final/pubspec.lock deleted file mode 100644 index 77a013df..00000000 --- a/035-statemanagement-api-integration/01-final/pubspec.lock +++ /dev/null @@ -1,210 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - responsive_builder: - dependency: "direct main" - description: - name: responsive_builder - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/035-statemanagement-api-integration/01-final/pubspec.yaml b/035-statemanagement-api-integration/01-final/pubspec.yaml deleted file mode 100644 index 9075312e..00000000 --- a/035-statemanagement-api-integration/01-final/pubspec.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: the_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - responsive_builder: ^0.2.0+2 - get_it: ^4.0.2 - stacked: ^1.6.0 - provider: ^4.1.3 - http: ^0.12.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/logo.png - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/035-statemanagement-api-integration/01-final/test/widget_test.dart b/035-statemanagement-api-integration/01-final/test/widget_test.dart deleted file mode 100644 index b9e0d165..00000000 --- a/035-statemanagement-api-integration/01-final/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:the_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/035-statemanagement-api-integration/01-final/web/index.html b/035-statemanagement-api-integration/01-final/web/index.html deleted file mode 100644 index b7d4703b..00000000 --- a/035-statemanagement-api-integration/01-final/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - the_basics - - - - - diff --git a/035-statemanagement-api-integration/the-basics-functions/.firebaserc b/035-statemanagement-api-integration/the-basics-functions/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/035-statemanagement-api-integration/the-basics-functions/.gitignore b/035-statemanagement-api-integration/the-basics-functions/.gitignore deleted file mode 100644 index f6268525..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/.gitignore +++ /dev/null @@ -1,65 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -firebase-debug.log* - -# Firebase cache -.firebase/ - -# Firebase config - -# Uncomment this if you'd like others to create their own Firebase project. -# For a team working on the same Firebase project(s), it is recommended to leave -# it commented so all members can deploy to the same project(s) in .firebaserc. -# .firebaserc - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env diff --git a/035-statemanagement-api-integration/the-basics-functions/firebase.json b/035-statemanagement-api-integration/the-basics-functions/firebase.json deleted file mode 100644 index a68a1958..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/firebase.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "functions": { - "predeploy": [ - "npm --prefix \"$RESOURCE_DIR\" run lint" - ] - } -} diff --git a/035-statemanagement-api-integration/the-basics-functions/functions/.eslintrc.json b/035-statemanagement-api-integration/the-basics-functions/functions/.eslintrc.json deleted file mode 100644 index 6b6beb65..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/functions/.eslintrc.json +++ /dev/null @@ -1,123 +0,0 @@ -{ - "parserOptions": { - // Required for certain syntax usages - "ecmaVersion": 2017 - }, - "plugins": [ - "promise" - ], - "extends": "eslint:recommended", - "rules": { - // Removed rule "disallow the use of console" from recommended eslint rules - "no-console": "off", - - // Removed rule "disallow multiple spaces in regular expressions" from recommended eslint rules - "no-regex-spaces": "off", - - // Removed rule "disallow the use of debugger" from recommended eslint rules - "no-debugger": "off", - - // Removed rule "disallow unused variables" from recommended eslint rules - "no-unused-vars": "off", - - // Removed rule "disallow mixed spaces and tabs for indentation" from recommended eslint rules - "no-mixed-spaces-and-tabs": "off", - - // Removed rule "disallow the use of undeclared variables unless mentioned in /*global */ comments" from recommended eslint rules - "no-undef": "off", - - // Warn against template literal placeholder syntax in regular strings - "no-template-curly-in-string": 1, - - // Warn if return statements do not either always or never specify values - "consistent-return": 1, - - // Warn if no return statements in callbacks of array methods - "array-callback-return": 1, - - // Require the use of === and !== - "eqeqeq": 2, - - // Disallow the use of alert, confirm, and prompt - "no-alert": 2, - - // Disallow the use of arguments.caller or arguments.callee - "no-caller": 2, - - // Disallow null comparisons without type-checking operators - "no-eq-null": 2, - - // Disallow the use of eval() - "no-eval": 2, - - // Warn against extending native types - "no-extend-native": 1, - - // Warn against unnecessary calls to .bind() - "no-extra-bind": 1, - - // Warn against unnecessary labels - "no-extra-label": 1, - - // Disallow leading or trailing decimal points in numeric literals - "no-floating-decimal": 2, - - // Warn against shorthand type conversions - "no-implicit-coercion": 1, - - // Warn against function declarations and expressions inside loop statements - "no-loop-func": 1, - - // Disallow new operators with the Function object - "no-new-func": 2, - - // Warn against new operators with the String, Number, and Boolean objects - "no-new-wrappers": 1, - - // Disallow throwing literals as exceptions - "no-throw-literal": 2, - - // Require using Error objects as Promise rejection reasons - "prefer-promise-reject-errors": 2, - - // Enforce “for” loop update clause moving the counter in the right direction - "for-direction": 2, - - // Enforce return statements in getters - "getter-return": 2, - - // Disallow await inside of loops - "no-await-in-loop": 2, - - // Disallow comparing against -0 - "no-compare-neg-zero": 2, - - // Warn against catch clause parameters from shadowing variables in the outer scope - "no-catch-shadow": 1, - - // Disallow identifiers from shadowing restricted names - "no-shadow-restricted-names": 2, - - // Enforce return statements in callbacks of array methods - "callback-return": 2, - - // Require error handling in callbacks - "handle-callback-err": 2, - - // Warn against string concatenation with __dirname and __filename - "no-path-concat": 1, - - // Prefer using arrow functions for callbacks - "prefer-arrow-callback": 1, - - // Return inside each then() to create readable and reusable Promise chains. - // Forces developers to return console logs and http calls in promises. - "promise/always-return": 2, - - //Enforces the use of catch() on un-returned promises - "promise/catch-or-return": 2, - - // Warn against nested then() or catch() statements - "promise/no-nesting": 1 - } -} diff --git a/035-statemanagement-api-integration/the-basics-functions/functions/.gitignore b/035-statemanagement-api-integration/the-basics-functions/functions/.gitignore deleted file mode 100644 index 40b878db..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/functions/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ \ No newline at end of file diff --git a/035-statemanagement-api-integration/the-basics-functions/functions/index.js b/035-statemanagement-api-integration/the-basics-functions/functions/index.js deleted file mode 100644 index de154973..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/functions/index.js +++ /dev/null @@ -1,44 +0,0 @@ -const functions = require("firebase-functions"); -var express = require("express"); -var cors = require("cors"); -var app = express(); - -app.use(cors()); - -const episodes = [ - { - title: "Setup, Build and Deploy", - duration: 14.07, - imageUrl: - "https://www.filledstacks.com/assets/static/32.81b85c1.ebb7a1aaddfef10313d7bab97243d449.jpg" - }, - { - title: "Adding a Responsive UI", - duration: 18.54, - imageUrl: - "https://www.filledstacks.com/assets/static/033.81b85c1.ebdf16d08a54fd37bc4cd5d1a0b0767f.jpg" - }, - { - title: "Layout Templates", - duration: 14.55, - imageUrl: - "https://www.filledstacks.com/assets/static/034.81b85c1.52d07852af687a77985f54c5eedecb82.jpg" - }, - { - title: "State Management and Api integration", - duration: 14.55, - imageUrl: - "https://www.filledstacks.com/assets/static/35.81b85c1.f9ab74c22bb56931e36a13783c29361f.jpg" - } -]; - -app.get("/courseEpisodes", (req, res, next) => { - res.json(episodes); -}); - -app.get("/episode", (req, res, next) => { - res.json(episodes[req.query.id]); -}); - -// Expose Express API as a single Cloud Function: -exports.thebasics = functions.https.onRequest(app); diff --git a/035-statemanagement-api-integration/the-basics-functions/functions/package-lock.json b/035-statemanagement-api-integration/the-basics-functions/functions/package-lock.json deleted file mode 100644 index b7b7f559..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/functions/package-lock.json +++ /dev/null @@ -1,2831 +0,0 @@ -{ - "name": "functions", - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", - "dev": true, - "requires": { - "@babel/highlight": "^7.0.0" - } - }, - "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", - "dev": true, - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - } - }, - "@firebase/app-types": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.4.8.tgz", - "integrity": "sha512-VTjWRooelMExK/rKArp6WqnWJJfi8Vs6VuDYDSeMcQ3NpSux2bW1dfJFuzYmiK1+37hEJP1F43DyUDv2lCJquw==" - }, - "@firebase/database": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.13.tgz", - "integrity": "sha512-B1+6Ns3jbpryDUi6ZohByXk8EPcuD5rUla1UchzdCjsU1waq06QyUrakow5Hr5RugqmziMAOfzpXid+wV4+bvw==", - "requires": { - "@firebase/database-types": "0.4.8", - "@firebase/logger": "0.1.31", - "@firebase/util": "0.2.34", - "faye-websocket": "0.11.3", - "tslib": "1.10.0" - } - }, - "@firebase/database-types": { - "version": "0.4.8", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.4.8.tgz", - "integrity": "sha512-bYGzvcwjGOSWuL43nldY3kD3ldPDLTiiOF0TItsJx2JdL58PzGiGaR71dvPJhueNBn+bwJ5KPJxpqTSVqM/j8w==", - "requires": { - "@firebase/app-types": "0.4.8" - } - }, - "@firebase/logger": { - "version": "0.1.31", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.31.tgz", - "integrity": "sha512-1OEJaCMMaaT0VleNwer3bocbd25beR6KZUaHBweLNHEFxaNvniSv+lm83g08dWLBml3ZVOb945hp6m8REFx6/Q==" - }, - "@firebase/util": { - "version": "0.2.34", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.34.tgz", - "integrity": "sha512-k8pNIzNLncvxDrqYVZN6/lnqZWy0OCJuZmK5urodARwdLy3sVLw5p9PWce0v9qzMO8tLdrBbCpnm1KJ8jg/kBQ==", - "requires": { - "tslib": "1.10.0" - } - }, - "@google-cloud/common": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.2.3.tgz", - "integrity": "sha512-lvw54mGKn8VqVIy2NzAk0l5fntBFX4UwQhHk6HaqkyCQ7WBl5oz4XhzKMtMilozF/3ObPcDogqwuyEWyZ6rnQQ==", - "optional": true, - "requires": { - "@google-cloud/projectify": "^1.0.0", - "@google-cloud/promisify": "^1.0.0", - "arrify": "^2.0.0", - "duplexify": "^3.6.0", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^5.5.0", - "retry-request": "^4.0.0", - "teeny-request": "^5.2.1" - } - }, - "@google-cloud/firestore": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-2.6.0.tgz", - "integrity": "sha512-5bpC7KZA+dCc+4Byp9yA7uvmM1kmVaXm6QiSQbf2Zz/rWftTr0N23f+5BKe9OXyY/nT44l2ygZjmP4Aw3ngLFg==", - "optional": true, - "requires": { - "bun": "^0.0.12", - "deep-equal": "^1.0.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^1.7.5", - "through2": "^3.0.0" - } - }, - "@google-cloud/paginator": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-2.0.2.tgz", - "integrity": "sha512-PCddVtZWvw0iZ3BLIsCXMBQvxUcS9O5CgfHBu8Zd8T3DCiML+oQED1odsbl3CQ9d3RrvBaj+eIh7Dv12D15PbA==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - } - }, - "@google-cloud/projectify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-1.0.2.tgz", - "integrity": "sha512-WnkGxvk4U1kAJpoS/Ehk+3MZXVW+XHHhwc/QyD6G8Za4xml3Fv+NRn/bYffl1TxSg+gE0N0mj9Shgc7e8+fl8A==", - "optional": true - }, - "@google-cloud/promisify": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-1.0.3.tgz", - "integrity": "sha512-Rufgfl3TnkIil3CjsH33Q6093zeoVqyqCdvtvgHuCqRJxCZYfaVPIyr8JViMeLTD4Ja630pRKKZVSjKggoVbNg==", - "optional": true - }, - "@google-cloud/storage": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-4.1.3.tgz", - "integrity": "sha512-79Ag+4eQq+KFJcKB85AimepoqTJOGuDLAmJd7JkLc8NM12a87JTCoGi65oi1eZ4H77AV0uUQxSS2Fo/hZL3+kQ==", - "optional": true, - "requires": { - "@google-cloud/common": "^2.1.1", - "@google-cloud/paginator": "^2.0.0", - "@google-cloud/promisify": "^1.0.0", - "arrify": "^2.0.0", - "compressible": "^2.0.12", - "concat-stream": "^2.0.0", - "date-and-time": "^0.11.0", - "duplexify": "^3.5.0", - "extend": "^3.0.2", - "gaxios": "^2.0.1", - "gcs-resumable-upload": "^2.2.4", - "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", - "mime-types": "^2.0.8", - "onetime": "^5.1.0", - "p-limit": "^2.2.0", - "pumpify": "^2.0.0", - "readable-stream": "^3.4.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "through2": "^3.0.0", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "@grpc/grpc-js": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-0.6.9.tgz", - "integrity": "sha512-r1nDOEEiYmAsVYBaS4DPPqdwPOXPw7YhVOnnpPdWhlNtKbYzPash6DqWTTza9gBiYMA5d2Wiq6HzrPqsRaP4yA==", - "optional": true, - "requires": { - "semver": "^6.2.0" - } - }, - "@grpc/proto-loader": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.3.tgz", - "integrity": "sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ==", - "optional": true, - "requires": { - "lodash.camelcase": "^4.3.0", - "protobufjs": "^6.8.6" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "optional": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "optional": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "optional": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "optional": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "optional": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "optional": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "optional": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "optional": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "optional": true - }, - "@types/body-parser": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.17.1.tgz", - "integrity": "sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.32", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.32.tgz", - "integrity": "sha512-4r8qa0quOvh7lGD0pre62CAb1oni1OO6ecJLGCezTmhQ8Fz50Arx9RUszryR8KlgK6avuSXvviL6yWyViQABOg==", - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.2.tgz", - "integrity": "sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.0.tgz", - "integrity": "sha512-Xnub7w57uvcBqFdIGoRg1KhNOeEj0vB6ykUM7uFWyxvbdE89GFyqgmUcanAriMr4YOxNFZBAWkfcWIb4WBPt3g==", - "requires": { - "@types/node": "*", - "@types/range-parser": "*" - } - }, - "@types/lodash": { - "version": "4.14.149", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", - "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==", - "dev": true - }, - "@types/long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", - "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==", - "optional": true - }, - "@types/mime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", - "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" - }, - "@types/node": { - "version": "8.10.59", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz", - "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==" - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "@types/serve-static": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", - "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", - "requires": { - "@types/express-serve-static-core": "*", - "@types/mime": "*" - } - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "optional": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", - "dev": true - }, - "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", - "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", - "dev": true - }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "optional": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", - "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "optional": true - }, - "bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "optional": true - }, - "bun": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/bun/-/bun-0.0.12.tgz", - "integrity": "sha512-Toms18J9DqnT+IfWkwxVTB2EaBprHvjlMWrTIsfX4xbu3ZBqVBwrERU0em1IgtRe04wT+wJxMlKHZok24hrcSQ==", - "optional": true, - "requires": { - "readable-stream": "~1.0.32" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "^2.0.0" - } - }, - "cli-width": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", - "dev": true - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", - "optional": true, - "requires": { - "mime-db": ">= 1.40.0 < 2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "optional": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "configstore": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.0.tgz", - "integrity": "sha512-eE/hvMs7qw7DlcB5JPRnthmrITuHMmACUJAp89v6PT6iOqzoLS7HRWhBtuHMlhNHo2AhUSA/3Dh1bKNJHcublQ==", - "optional": true, - "requires": { - "dot-prop": "^5.1.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "optional": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "optional": true - }, - "date-and-time": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-0.11.0.tgz", - "integrity": "sha512-VyzhHurex4wlg9oMszn7O+kxHchphWjzDn7Mv0WfkFKI6hSNOQePpTBFGsnRakvLNzQKXqPBAVV8DOxUGtUxqA==", - "optional": true - }, - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-equal": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", - "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", - "optional": true, - "requires": { - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "optional": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", - "requires": { - "streamsearch": "0.1.2" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "optional": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "optional": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "optional": true, - "requires": { - "once": "^1.4.0" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "optional": true - }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==", - "optional": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "optional": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", - "debug": "^4.0.1", - "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", - "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", - "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", - "ignore": "^4.0.6", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", - "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "eslint-plugin-promise": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", - "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", - "dev": true - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^1.1.0" - } - }, - "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true - }, - "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", - "dev": true, - "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, - "requires": { - "estraverse": "^4.0.0" - } - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "optional": true - }, - "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "optional": true - }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-text-encoding": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", - "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==", - "optional": true - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, - "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } - }, - "firebase-admin": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-8.8.0.tgz", - "integrity": "sha512-IKtyL7doZu3Sh3pCz+O7vFWc/UwxEfXe263X/bPbucu/qEsM+5UdljIklnInSMunO+A1BUXKtsKkQf91iZQ2Ew==", - "requires": { - "@firebase/database": "^0.5.11", - "@google-cloud/firestore": "^2.6.0", - "@google-cloud/storage": "^4.1.2", - "@types/node": "^8.0.53", - "dicer": "^0.3.0", - "jsonwebtoken": "8.1.0", - "node-forge": "0.7.4" - } - }, - "firebase-functions": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.3.0.tgz", - "integrity": "sha512-dP6PCG+OwR6RtFpOqwPsLnfiCr3CwXAm/SVGMbO53vDAk0nhUQ1WGAyHDYmIyMAkaLJkIKGwDnX7XmZ5+yAg7g==", - "requires": { - "@types/express": "^4.17.0", - "cors": "^2.8.5", - "express": "^4.17.1", - "jsonwebtoken": "^8.5.1", - "lodash": "^4.17.14" - }, - "dependencies": { - "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "firebase-functions-test": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.1.7.tgz", - "integrity": "sha512-/zVQhaUZ+M7z25aUaZSIah0MIDZIfnRfQxtHYTE8hgUgODmKdaMX20vh5Gv23hnCPauIHuYb7XFTUOZiWU1udA==", - "dev": true, - "requires": { - "@types/lodash": "^4.14.104", - "lodash": "^4.17.5" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } - }, - "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", - "dev": true - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" - }, - "gaxios": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.1.0.tgz", - "integrity": "sha512-Gtpb5sdQmb82sgVkT2GnS2n+Kx4dlFwbeMYcDlD395aEvsLCSQXJJcHt7oJ2LrGxDEAeiOkK79Zv2A8Pzt6CFg==", - "optional": true, - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^3.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.3.0" - } - }, - "gcp-metadata": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-3.2.2.tgz", - "integrity": "sha512-vR7kcJMCYJG/mYWp/a1OszdOqnLB/XW1GorWW1hc1lWVNL26L497zypWb9cG0CYDQ4Bl1Wk0+fSZFFjwJlTQgQ==", - "optional": true, - "requires": { - "gaxios": "^2.1.0", - "json-bigint": "^0.3.0" - } - }, - "gcs-resumable-upload": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-2.3.1.tgz", - "integrity": "sha512-zEO7L+jz99VznQsbsF7vFTnIFbSu+CjdJqt5htnjIrfsp5j+QCVBvbbKdqpaTfCPzpUPYj1Q9O9DhIh/8newfA==", - "optional": true, - "requires": { - "abort-controller": "^3.0.0", - "configstore": "^5.0.0", - "gaxios": "^2.0.0", - "google-auth-library": "^5.0.0", - "pumpify": "^2.0.0", - "stream-events": "^1.0.4" - } - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - }, - "google-auth-library": { - "version": "5.5.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.5.1.tgz", - "integrity": "sha512-zCtjQccWS/EHYyFdXRbfeSGM/gW+d7uMAcVnvXRnjBXON5ijo6s0nsObP0ifqileIDSbZjTlLtgo+UoN8IFJcg==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "fast-text-encoding": "^1.0.0", - "gaxios": "^2.1.0", - "gcp-metadata": "^3.2.0", - "gtoken": "^4.1.0", - "jws": "^3.1.5", - "lru-cache": "^5.0.0" - } - }, - "google-gax": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-1.11.1.tgz", - "integrity": "sha512-v/APF2G5h2nS5R/1DW2vsgloaMu2/B3xjHdAptR1yUwZpEd9rxPTlhqosrjl/VRu+gWGr9JZN19ZgJTXQ/Db6Q==", - "optional": true, - "requires": { - "@grpc/grpc-js": "0.6.9", - "@grpc/proto-loader": "^0.5.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^3.6.0", - "google-auth-library": "^5.0.0", - "is-stream-ended": "^0.1.4", - "lodash.at": "^4.6.0", - "lodash.has": "^4.5.2", - "node-fetch": "^2.6.0", - "protobufjs": "^6.8.8", - "retry-request": "^4.0.0", - "semver": "^6.0.0", - "walkdir": "^0.4.0" - } - }, - "google-p12-pem": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.3.tgz", - "integrity": "sha512-Tq2kBCANxYYPxaBpTgCpRfdoPs9+/lNzc/Iaee4kuMVW5ascD+HwhpBsTLwH85C9Ev4qfB8KKHmpPQYyD2vg2w==", - "optional": true, - "requires": { - "node-forge": "^0.9.0" - }, - "dependencies": { - "node-forge": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", - "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==", - "optional": true - } - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "optional": true - }, - "gtoken": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.1.3.tgz", - "integrity": "sha512-ofW+FiXjswyKdkjMcDbe6E4K7cDDdE82dGDhZIc++kUECqaE7MSErf6arJPAjcnYn1qxE1/Ti06qQuqgVusovQ==", - "optional": true, - "requires": { - "gaxios": "^2.1.0", - "google-p12-pem": "^2.0.0", - "jws": "^3.1.5", - "mime": "^2.2.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "hash-stream-validation": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.2.tgz", - "integrity": "sha512-cMlva5CxWZOrlS/cY0C+9qAzesn5srhFA8IT1VPiHc9bWWBLkJfEUIZr7MWoi89oOOGmpg8ymchaOjiArsGu5A==", - "optional": true, - "requires": { - "through2": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "optional": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "optional": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "optional": true - } - } - }, - "https-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", - "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", - "optional": true, - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "inquirer": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", - "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", - "dev": true, - "requires": { - "ansi-escapes": "^3.2.0", - "chalk": "^2.4.2", - "cli-cursor": "^2.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^2.0.0", - "lodash": "^4.17.12", - "mute-stream": "0.0.7", - "run-async": "^2.2.0", - "rxjs": "^6.4.0", - "string-width": "^2.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "optional": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "optional": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "optional": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "optional": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "optional": true - }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "optional": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "optional": true - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "optional": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "json-bigint": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", - "optional": true, - "requires": { - "bignumber.js": "^7.0.0" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "jsonwebtoken": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz", - "integrity": "sha1-xjl80uX9WD1lwAeoPce7eOaYK4M=", - "requires": { - "jws": "^3.1.4", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.at": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=", - "optional": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "optional": true - }, - "lodash.has": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=", - "optional": true - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "optional": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "optional": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", - "optional": true, - "requires": { - "semver": "^6.0.0" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "optional": true - }, - "mime-db": { - "version": "1.42.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.42.0.tgz", - "integrity": "sha512-UbfJCR4UAVRNgMpfImz05smAXK7+c+ZntjaA26ANtkXLlOe947Aag5zdIcKQULAiF9Cq4WxBi9jUs5zkA84bYQ==" - }, - "mime-types": { - "version": "2.1.25", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.25.tgz", - "integrity": "sha512-5KhStqB5xpTAeGqKBAMgwaYMnQik7teQN4IAzC7npDv6kzeU6prfkR67bc87J1kWMPGkoaZSq1npmexMgkmEVg==", - "requires": { - "mime-db": "1.42.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "optional": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.4.tgz", - "integrity": "sha512-8Df0906+tq/omxuCZD6PqhPaQDYuyJ1d+VITgxoIA8zvQd1ru+nMJcDChHH324MWitIgbVkAkQoGEEVJNpn/PA==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" - }, - "object-is": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz", - "integrity": "sha1-CqYOyZiaCz7Xlc9NBvYs8a1lObY=", - "optional": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "optional": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "optional": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-limit": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz", - "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==", - "optional": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "optional": true - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "optional": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "protobufjs": { - "version": "6.8.8", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "10.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.5.tgz", - "integrity": "sha512-RElZIr/7JreF1eY6oD5RF3kpmdcreuQPjg5ri4oQ5g9sq7YWU8HkfB3eH8GwAwxf5OaCh0VPi7r4N/yoTGelrA==", - "optional": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "optional": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "optional": true, - "requires": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "optional": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - }, - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "regexp.prototype.flags": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.2.0.tgz", - "integrity": "sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA==", - "optional": true, - "requires": { - "define-properties": "^1.1.2" - } - }, - "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "^2.0.0", - "signal-exit": "^3.0.2" - }, - "dependencies": { - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "^1.0.0" - } - } - } - }, - "retry-request": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz", - "integrity": "sha512-BINDzVtLI2BDukjWmjAIRZ0oglnCAkpP2vQjM3jdLhmT62h0xnQgciPwBRDAvHqpkPT2Wo1XuUyLyn6nbGrZQQ==", - "optional": true, - "requires": { - "debug": "^4.1.1", - "through2": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "optional": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "^2.1.0" - } - }, - "rxjs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", - "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "snakeize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", - "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", - "optional": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "optional": true, - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "optional": true - }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "optional": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "optional": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "teeny-request": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-5.3.1.tgz", - "integrity": "sha512-hnUeun3xryzv92FbrnprltcdeDfSVaGFBlFPRvKJ2fO/ioQx9N0aSUbbXSfTO+ArRXine1gSWdWFWcgfrggWXw==", - "optional": true, - "requires": { - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^3.0.0", - "node-fetch": "^2.2.0", - "stream-events": "^1.0.5", - "uuid": "^3.3.2" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "optional": true, - "requires": { - "readable-stream": "2 || 3" - }, - "dependencies": { - "readable-stream": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", - "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "optional": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } - } - }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "optional": true - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "optional": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "optional": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "optional": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "optional": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", - "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", - "optional": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", - "optional": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "optional": true - }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "optional": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", - "optional": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "optional": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - } - } -} diff --git a/035-statemanagement-api-integration/the-basics-functions/functions/package.json b/035-statemanagement-api-integration/the-basics-functions/functions/package.json deleted file mode 100644 index de5f03d7..00000000 --- a/035-statemanagement-api-integration/the-basics-functions/functions/package.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "name": "functions", - "description": "Cloud Functions for Firebase", - "scripts": { - "lint": "eslint .", - "serve": "firebase serve --only functions", - "shell": "firebase functions:shell", - "start": "npm run shell", - "deploy": "firebase deploy --only functions", - "logs": "firebase functions:log" - }, - "engines": { - "node": "8" - }, - "dependencies": { - "firebase-admin": "^8.0.0", - "firebase-functions": "^3.1.0" - }, - "devDependencies": { - "eslint": "^5.12.0", - "eslint-plugin-promise": "^4.0.1", - "firebase-functions-test": "^0.1.6" - }, - "private": true -} diff --git a/036-hover-in-flutter-web/.firebaserc b/036-hover-in-flutter-web/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/036-hover-in-flutter-web/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/036-hover-in-flutter-web/.gitignore b/036-hover-in-flutter-web/.gitignore deleted file mode 100644 index 36a616eb..00000000 --- a/036-hover-in-flutter-web/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/036-hover-in-flutter-web/.metadata b/036-hover-in-flutter-web/.metadata deleted file mode 100644 index c17efdcf..00000000 --- a/036-hover-in-flutter-web/.metadata +++ /dev/null @@ -1,10 +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: 8e0799a657051bf540d98b8aecf9cfa1325f3f71 - channel: master - -project_type: app diff --git a/036-hover-in-flutter-web/README.md b/036-hover-in-flutter-web/README.md deleted file mode 100644 index e42c305e..00000000 --- a/036-hover-in-flutter-web/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# the_basics - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/036-hover-in-flutter-web/assets/fonts/OpenSans-ExtraBold.ttf b/036-hover-in-flutter-web/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/036-hover-in-flutter-web/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/036-hover-in-flutter-web/assets/fonts/OpenSans-Regular.ttf b/036-hover-in-flutter-web/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/036-hover-in-flutter-web/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/036-hover-in-flutter-web/assets/logo.png b/036-hover-in-flutter-web/assets/logo.png deleted file mode 100644 index bcd4c4b9..00000000 Binary files a/036-hover-in-flutter-web/assets/logo.png and /dev/null differ diff --git a/036-hover-in-flutter-web/firebase.json b/036-hover-in-flutter-web/firebase.json deleted file mode 100644 index 66037326..00000000 --- a/036-hover-in-flutter-web/firebase.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosting": { - "public": "build/web", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/036-hover-in-flutter-web/lib/constants/app_colors.dart b/036-hover-in-flutter-web/lib/constants/app_colors.dart deleted file mode 100644 index 4524aca0..00000000 --- a/036-hover-in-flutter-web/lib/constants/app_colors.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color primaryColor = Color.fromARGB(255, 31, 229, 146); \ No newline at end of file diff --git a/036-hover-in-flutter-web/lib/datamodels/episode_item_model.dart b/036-hover-in-flutter-web/lib/datamodels/episode_item_model.dart deleted file mode 100644 index 397adab3..00000000 --- a/036-hover-in-flutter-web/lib/datamodels/episode_item_model.dart +++ /dev/null @@ -1,16 +0,0 @@ -class EpisodeItemModel { - final String title; - final double duration; - final String imageUrl; - - EpisodeItemModel({ - this.title, - this.duration, - this.imageUrl, - }); - - EpisodeItemModel.fromJson(Map map) - : title = map['title'], - duration = map['duration'], - imageUrl = map['imageUrl']; -} diff --git a/036-hover-in-flutter-web/lib/datamodels/navbar_item_model.dart b/036-hover-in-flutter-web/lib/datamodels/navbar_item_model.dart deleted file mode 100644 index c3b4d632..00000000 --- a/036-hover-in-flutter-web/lib/datamodels/navbar_item_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class NavBarItemModel { - final String title; - final String navigationPath; - final IconData iconData; - - NavBarItemModel({ - this.title, - this.navigationPath, - this.iconData, - }); -} diff --git a/036-hover-in-flutter-web/lib/datamodels/season_details_model.dart b/036-hover-in-flutter-web/lib/datamodels/season_details_model.dart deleted file mode 100644 index 5bb623fc..00000000 --- a/036-hover-in-flutter-web/lib/datamodels/season_details_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class SeasonDetailsModel { - final String title; - final String description; - - SeasonDetailsModel({ - @required this.title, - @required this.description, - }); -} diff --git a/036-hover-in-flutter-web/lib/extensions/hover_extensions.dart b/036-hover-in-flutter-web/lib/extensions/hover_extensions.dart deleted file mode 100644 index 33cc115b..00000000 --- a/036-hover-in-flutter-web/lib/extensions/hover_extensions.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'dart:html' as html; - -import 'package:the_basics/widgets/translate_on_hover.dart'; - -extension HoverExtensions on Widget { - static final appContainer = - html.window.document.getElementById('app-container'); - - Widget get showCursorOnHover { - return MouseRegion( - child: this, // the widget we're using the extension on - onHover: (event) => appContainer.style.cursor = 'pointer', - onExit: (event) => appContainer.style.cursor = 'default', - ); - } - - Widget get moveUpOnHover { - return TranslateOnHover( - child: this, - ); - } -} diff --git a/036-hover-in-flutter-web/lib/locator.dart b/036-hover-in-flutter-web/lib/locator.dart deleted file mode 100644 index a0c940fc..00000000 --- a/036-hover-in-flutter-web/lib/locator.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:the_basics/services/api.dart'; -import 'package:the_basics/services/navigation_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => Api()); -} \ No newline at end of file diff --git a/036-hover-in-flutter-web/lib/main.dart b/036-hover-in-flutter-web/lib/main.dart deleted file mode 100644 index 135075f6..00000000 --- a/036-hover-in-flutter-web/lib/main.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/views/layout_template/layout_template.dart'; - -import 'locator.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - textTheme: Theme.of(context).textTheme.apply(fontFamily: 'Open Sans'), - ), - home: LayoutTemplate(), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/routing/route_names.dart b/036-hover-in-flutter-web/lib/routing/route_names.dart deleted file mode 100644 index c8aeef50..00000000 --- a/036-hover-in-flutter-web/lib/routing/route_names.dart +++ /dev/null @@ -1,3 +0,0 @@ -const String HomeRoute = 'home'; -const String AboutRoute = 'about'; -const String EpisodesRoute = 'episodes'; diff --git a/036-hover-in-flutter-web/lib/routing/router.dart b/036-hover-in-flutter-web/lib/routing/router.dart deleted file mode 100644 index d013f18d..00000000 --- a/036-hover-in-flutter-web/lib/routing/router.dart +++ /dev/null @@ -1,48 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/views/about/about_view.dart'; -import 'package:the_basics/views/episodes/episodes_view.dart'; -import 'package:the_basics/views/home/home_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case HomeRoute: - return _getPageRoute(HomeView(), settings); - case AboutRoute: - return _getPageRoute(AboutView(), settings); - case EpisodesRoute: - return _getPageRoute(EpisodesView(), settings); - default: - return _getPageRoute(HomeView(), settings); - } -} - -PageRoute _getPageRoute(Widget child, RouteSettings settings) { - return _FadeRoute(child: child, routeName: settings.name); -} - -class _FadeRoute extends PageRouteBuilder { - final Widget child; - final String routeName; - _FadeRoute({this.child, this.routeName}) - : super( - settings: RouteSettings(name: routeName), - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) => - child, - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => - FadeTransition( - opacity: animation, - child: child, - ), - ); -} diff --git a/036-hover-in-flutter-web/lib/services/api.dart b/036-hover-in-flutter-web/lib/services/api.dart deleted file mode 100644 index ff9b4094..00000000 --- a/036-hover-in-flutter-web/lib/services/api.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:http/http.dart' as http; -import 'dart:convert'; - -import 'package:the_basics/datamodels/episode_item_model.dart'; - -class Api { - static const String _apiEndpoint = - 'https://us-central1-thebasics-2f123.cloudfunctions.net/thebasics'; - - Future getEpisodes() async { - var response = await http.get('$_apiEndpoint/courseEpisodes'); - - if (response.statusCode == 200) { - var episodes = (json.decode(response.body) as List) - .map((episode) => EpisodeItemModel.fromJson(episode)) - .toList(); - return episodes; - } - - // something wrong happened - return 'Could not fetch the episodes at this time'; - } -} diff --git a/036-hover-in-flutter-web/lib/services/navigation_service.dart b/036-hover-in-flutter-web/lib/services/navigation_service.dart deleted file mode 100644 index d4a51a00..00000000 --- a/036-hover-in-flutter-web/lib/services/navigation_service.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - final GlobalKey navigatorKey = GlobalKey(); - - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); - } - - void goBack() { - return navigatorKey.currentState.pop(); - } -} diff --git a/036-hover-in-flutter-web/lib/styles/text_styles.dart b/036-hover-in-flutter-web/lib/styles/text_styles.dart deleted file mode 100644 index de84920b..00000000 --- a/036-hover-in-flutter-web/lib/styles/text_styles.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -/// Returns the style for a page title based on the [deviceScreenType] passed in. -TextStyle titleTextStyle(DeviceScreenType deviceScreenType) { - double titleSize = deviceScreenType == DeviceScreenType.mobile ? 50 : 80; - return TextStyle( - fontWeight: FontWeight.w800, height: 0.9, fontSize: titleSize); -} - -/// Return the style for description text on a page based on the [deviceScreenType] passed in. -TextStyle descriptionTextStyle(DeviceScreenType deviceScreenType) { - double descriptionSize = - deviceScreenType == DeviceScreenType.mobile ? 16 : 21; - - return TextStyle( - fontSize: descriptionSize, - height: 1.7, - ); -} diff --git a/036-hover-in-flutter-web/lib/viewmodels/episodes_view_model.dart b/036-hover-in-flutter-web/lib/viewmodels/episodes_view_model.dart deleted file mode 100644 index e7a17521..00000000 --- a/036-hover-in-flutter-web/lib/viewmodels/episodes_view_model.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/api.dart'; - -class EpisodesViewModel extends ChangeNotifier { - final _api = locator(); - - List _episodes; - List get episodes => _episodes; - - Future getEpisodes() async { - var episodeResults = await _api.getEpisodes(); - - if (episodeResults is String) { - // show error - } else { - _episodes = episodeResults; - } - - notifyListeners(); - } -} diff --git a/036-hover-in-flutter-web/lib/views/about/about_view.dart b/036-hover-in-flutter-web/lib/views/about/about_view.dart deleted file mode 100644 index 34741b6f..00000000 --- a/036-hover-in-flutter-web/lib/views/about/about_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class AboutView extends StatelessWidget { - const AboutView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.red, - ); - } -} diff --git a/036-hover-in-flutter-web/lib/views/episodes/episodes_view.dart b/036-hover-in-flutter-web/lib/views/episodes/episodes_view.dart deleted file mode 100644 index 5bed4225..00000000 --- a/036-hover-in-flutter-web/lib/views/episodes/episodes_view.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/viewmodels/episodes_view_model.dart'; -import 'package:the_basics/widgets/episodes_list/episodes_list.dart'; -import 'package:the_basics/widgets/season_details/season_details.dart'; - -class EpisodesView extends StatelessWidget { - const EpisodesView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => EpisodesViewModel(), - onModelReady: (model) => model.getEpisodes(), - builder: (context, model, child) => SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - SizedBox( - height: 100, - ), - SeasonDetails( - details: SeasonDetailsModel( - title: 'SEASON 1', - description: - 'This season covers the absolute basics of Flutter Web Dev to get us up and running with a basic web app.', - ), - ), - SizedBox( - height: 50, - ), - model.episodes == null - ? CircularProgressIndicator() - : EpisodesList(episodes: model.episodes), - ], - )), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/views/home/home_content_desktop.dart b/036-hover-in-flutter-web/lib/views/home/home_content_desktop.dart deleted file mode 100644 index 4fab7a21..00000000 --- a/036-hover-in-flutter-web/lib/views/home/home_content_desktop.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentDesktop extends StatelessWidget { - const HomeContentDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Row( - children: [ - CourseDetails(), - Expanded( - child: Center( - child: CallToAction('Join Course'), - ), - ) - ], - ); - } -} diff --git a/036-hover-in-flutter-web/lib/views/home/home_content_mobile.dart b/036-hover-in-flutter-web/lib/views/home/home_content_mobile.dart deleted file mode 100644 index 028c8d38..00000000 --- a/036-hover-in-flutter-web/lib/views/home/home_content_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentMobile extends StatelessWidget { - const HomeContentMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CourseDetails(), - SizedBox( - height: 100, - ), - CallToAction('Join Course'), - ], - ); - } -} diff --git a/036-hover-in-flutter-web/lib/views/home/home_view.dart b/036-hover-in-flutter-web/lib/views/home/home_view.dart deleted file mode 100644 index a138243d..00000000 --- a/036-hover-in-flutter-web/lib/views/home/home_view.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/views/home/home_content_desktop.dart'; -import 'package:the_basics/views/home/home_content_mobile.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: HomeContentMobile(), - desktop: HomeContentDesktop(), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/views/layout_template/layout_template.dart b/036-hover-in-flutter-web/lib/views/layout_template/layout_template.dart deleted file mode 100644 index b6d5030d..00000000 --- a/036-hover-in-flutter-web/lib/views/layout_template/layout_template.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/routing/router.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/centered_view/centered_view.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer.dart'; - -class LayoutTemplate extends StatelessWidget { - const LayoutTemplate({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Scaffold( - drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? NavigationDrawer() - : null, - backgroundColor: Colors.white, - body: CenteredView( - child: Column( - children: [ - NavigationBar(), - Expanded( - child: Navigator( - key: locator().navigatorKey, - onGenerateRoute: generateRoute, - initialRoute: HomeRoute, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action.dart b/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action.dart deleted file mode 100644 index 13ceb078..00000000 --- a/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_mobile.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_tablet_desktop.dart'; -import 'package:the_basics/extensions/hover_extensions.dart'; - -class CallToAction extends StatelessWidget { - final String title; - CallToAction(this.title); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: CallToActionMobile(title), - tablet: CallToActionTabletDesktop(title), - ).showCursorOnHover.moveUpOnHover; - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action_mobile.dart b/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action_mobile.dart deleted file mode 100644 index d2455218..00000000 --- a/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action_mobile.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionMobile extends StatelessWidget { - final String title; - const CallToActionMobile(this.title); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - alignment: Alignment.center, - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart b/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart deleted file mode 100644 index 0ea18c80..00000000 --- a/036-hover-in-flutter-web/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionTabletDesktop extends StatelessWidget { - final String title; - const CallToActionTabletDesktop(this.title); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15), - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/centered_view/centered_view.dart b/036-hover-in-flutter-web/lib/widgets/centered_view/centered_view.dart deleted file mode 100644 index 1aed138b..00000000 --- a/036-hover-in-flutter-web/lib/widgets/centered_view/centered_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class CenteredView extends StatelessWidget { - final Widget child; - const CenteredView({Key key, this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 60), - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 1200), - child: child, - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/course_details/course_details.dart b/036-hover-in-flutter-web/lib/widgets/course_details/course_details.dart deleted file mode 100644 index 299ed635..00000000 --- a/036-hover-in-flutter-web/lib/widgets/course_details/course_details.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class CourseDetails extends StatelessWidget { - const CourseDetails({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - var textAlignment = - sizingInformation.deviceScreenType == DeviceScreenType.desktop - ? TextAlign.left - : TextAlign.center; - - return Container( - width: 600, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'FLUTTER WEB.\nTHE BASICS', - style: titleTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ), - SizedBox( - height: 30, - ), - Text( - 'In this course we will go over the basics of using Flutter Web for website development. Topics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.', - style: descriptionTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ) - ], - ), - ); - }, - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/episodes_list/episode_item.dart b/036-hover-in-flutter-web/lib/widgets/episodes_list/episode_item.dart deleted file mode 100644 index de43ac02..00000000 --- a/036-hover-in-flutter-web/lib/widgets/episodes_list/episode_item.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; -import 'package:the_basics/extensions/hover_extensions.dart'; - -class EpisodeItem extends StatelessWidget { - final EpisodeItemModel model; - const EpisodeItem({ - Key key, - this.model, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Card( - color: Colors.white, - elevation: 2, - child: SizedBox( - width: 360, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 180, - child: Image.network(model.imageUrl, fit: BoxFit.cover,), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15.0, - vertical: 20, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - model.title, - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 14, - ), - softWrap: true, - ), - Text( - '${model.duration} minutes', - style: TextStyle(fontSize: 10), - ) - ], - ), - ), - ], - ), - ), - ).showCursorOnHover; - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/episodes_list/episodes_list.dart b/036-hover-in-flutter-web/lib/widgets/episodes_list/episodes_list.dart deleted file mode 100644 index b7d92041..00000000 --- a/036-hover-in-flutter-web/lib/widgets/episodes_list/episodes_list.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; - -import 'episode_item.dart'; - -class EpisodesList extends StatelessWidget { - final List episodes; - EpisodesList({this.episodes}); - - @override - Widget build(BuildContext context) { - return Wrap( - spacing: 30, - runSpacing: 30, - children: [ - ...episodes.map( - (episode) => EpisodeItem(model: episode), - ) - ], - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item.dart b/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item.dart deleted file mode 100644 index 38a23432..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_desktop.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_mobile.dart'; -import 'package:the_basics/extensions/hover_extensions.dart'; - -class NavBarItem extends StatelessWidget { - final String title; - final String navigationPath; - final IconData icon; - const NavBarItem(this.title, this.navigationPath, {this.icon}); - - @override - Widget build(BuildContext context) { - var model = NavBarItemModel( - title: title, - navigationPath: navigationPath, - iconData: icon, - ); - return GestureDetector( - onTap: () { - // DON'T EVER USE A SERVICE DIRECTLY IN THE UI TO CHANGE ANY KIND OF STATE - // SERVICES SHOULD ONLY BE USED FROM A VIEWMODEL - locator().navigateTo(navigationPath); - }, - child: Provider.value( - value: model, - child: ScreenTypeLayout( - tablet: NavBarItemTabletDesktop(), - mobile: NavBarItemMobile(), - ).showCursorOnHover.moveUpOnHover, - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item_desktop.dart b/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item_desktop.dart deleted file mode 100644 index 49dd9b81..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item_desktop.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemTabletDesktop extends ViewModelWidget { - @override - Widget build(BuildContext context, NavBarItemModel model) { - return Text( - model.title, - style: TextStyle(fontSize: 18), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item_mobile.dart b/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item_mobile.dart deleted file mode 100644 index beee7c38..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navbar_item/navbar_item_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemMobile extends ViewModelWidget { - @override - Widget build(BuildContext context, NavBarItemModel model) { - return Padding( - padding: const EdgeInsets.only(left: 30, top: 60), - child: Row( - children: [ - Icon(model.iconData), - SizedBox( - width: 30, - ), - Text( - model.title, - style: TextStyle(fontSize: 18), - ) - ], - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navbar_logo.dart b/036-hover-in-flutter-web/lib/widgets/navigation_bar/navbar_logo.dart deleted file mode 100644 index 483fe20f..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navbar_logo.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavBarLogo extends StatelessWidget { - const NavBarLogo({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 80, - width: 150, - child: Image.asset('assets/logo.png'), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar.dart b/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar.dart deleted file mode 100644 index a09d1e34..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_tablet_desktop.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_mobile.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class NavigationBar extends StatelessWidget { - const NavigationBar({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: NavigationBarMobile(), - tablet: NavigationBarTabletDesktop(), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar_mobile.dart b/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar_mobile.dart deleted file mode 100644 index 387f852c..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_logo.dart'; - -class NavigationBarMobile extends StatelessWidget { - const NavigationBarMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 80, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: Icon(Icons.menu), - onPressed: () {}, - ), - NavBarLogo() - ], - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart b/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart deleted file mode 100644 index 6f622c31..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; - -import 'navbar_logo.dart'; - -class NavigationBarTabletDesktop extends StatelessWidget { - const NavigationBarTabletDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - NavBarLogo(), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - NavBarItem('Episodes', EpisodesRoute), - SizedBox( - width: 60, - ), - NavBarItem('About', AboutRoute), - ], - ) - ], - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navigation_drawer/navigation_drawer.dart b/036-hover-in-flutter-web/lib/widgets/navigation_drawer/navigation_drawer.dart deleted file mode 100644 index 257d4153..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navigation_drawer/navigation_drawer.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer_header.dart'; - -class NavigationDrawer extends StatelessWidget { - const NavigationDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 300, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(color: Colors.black12, blurRadius: 16), - ], - ), - child: Column( - children: [ - NavigationDrawerHeader(), - // BONUS: Combine the UI for this widget with the NavBarItem and make it responsive. - // The UI for the current DrawerItem shows when it's in mobile, else it shows the NavBarItem ui. - NavBarItem( - 'Episodes', - EpisodesRoute, - icon: Icons.videocam, - ), - NavBarItem( - 'About', - AboutRoute, - icon: Icons.help, - ), - ], - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/navigation_drawer/navigation_drawer_header.dart b/036-hover-in-flutter-web/lib/widgets/navigation_drawer/navigation_drawer_header.dart deleted file mode 100644 index 0b96e2af..00000000 --- a/036-hover-in-flutter-web/lib/widgets/navigation_drawer/navigation_drawer_header.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class NavigationDrawerHeader extends StatelessWidget { - const NavigationDrawerHeader({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 150, - color: primaryColor, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'SKILL UP NOW', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white), - ), - Text( - 'TAP HERE', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/season_details/season_details.dart b/036-hover-in-flutter-web/lib/widgets/season_details/season_details.dart deleted file mode 100644 index 7b4b5a0f..00000000 --- a/036-hover-in-flutter-web/lib/widgets/season_details/season_details.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/widgets/season_details/season_details_desktop.dart'; -import 'package:the_basics/widgets/season_details/season_details_mobile.dart'; - -class SeasonDetails extends StatelessWidget { - final SeasonDetailsModel details; - const SeasonDetails({Key key, this.details}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Provider.value( - value: details, - child: ScreenTypeLayout( - desktop: SeasonDetailsDesktop(), - mobile: SeasonDetailsMobile(), - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/season_details/season_details_desktop.dart b/036-hover-in-flutter-web/lib/widgets/season_details/season_details_desktop.dart deleted file mode 100644 index b98619a8..00000000 --- a/036-hover-in-flutter-web/lib/widgets/season_details/season_details_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsDesktop extends ViewModelWidget { - @override - Widget build(BuildContext context, SeasonDetailsModel details) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - width: 50, - ), - Expanded( - child: Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ) - ], - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/season_details/season_details_mobile.dart b/036-hover-in-flutter-web/lib/widgets/season_details/season_details_mobile.dart deleted file mode 100644 index f6d5ec3d..00000000 --- a/036-hover-in-flutter-web/lib/widgets/season_details/season_details_mobile.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsMobile extends ViewModelWidget { - @override - Widget build(BuildContext context, SeasonDetailsModel details) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Column( - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - height: 50, - ), - Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ], - ), - ); - } -} diff --git a/036-hover-in-flutter-web/lib/widgets/translate_on_hover.dart b/036-hover-in-flutter-web/lib/widgets/translate_on_hover.dart deleted file mode 100644 index c966057f..00000000 --- a/036-hover-in-flutter-web/lib/widgets/translate_on_hover.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; - -class TranslateOnHover extends StatefulWidget { - final Widget child; - TranslateOnHover({Key key, this.child}) : super(key: key); - - @override - _TranslateOnHoverState createState() => _TranslateOnHoverState(); -} - -class _TranslateOnHoverState extends State { - final nonHoverTransform = Matrix4.identity(); - final hoverTransform = Matrix4.identity()..translate(0, -5, 0); - - bool _hovering = false; - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (e) => _mouseEnter(true), - onExit: (e) => _mouseEnter(false), - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - child: widget.child, - transform: _hovering ? hoverTransform : nonHoverTransform, - ), - ); - } - - void _mouseEnter(bool hovering) { - setState(() { - _hovering = hovering; - }); - } -} diff --git a/036-hover-in-flutter-web/pubspec.lock b/036-hover-in-flutter-web/pubspec.lock deleted file mode 100644 index 379da8e7..00000000 --- a/036-hover-in-flutter-web/pubspec.lock +++ /dev/null @@ -1,210 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - responsive_builder: - dependency: "direct main" - description: - name: responsive_builder - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/036-hover-in-flutter-web/pubspec.yaml b/036-hover-in-flutter-web/pubspec.yaml deleted file mode 100644 index a6b581b1..00000000 --- a/036-hover-in-flutter-web/pubspec.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: the_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.6.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - responsive_builder: ^0.2.0+2 - get_it: ^4.0.2 - stacked: ^1.6.0 - provider: ^4.1.3 - http: ^0.12.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/logo.png - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/036-hover-in-flutter-web/test/widget_test.dart b/036-hover-in-flutter-web/test/widget_test.dart deleted file mode 100644 index b9e0d165..00000000 --- a/036-hover-in-flutter-web/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:the_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/036-hover-in-flutter-web/web/index.html b/036-hover-in-flutter-web/web/index.html deleted file mode 100644 index 64fae6cf..00000000 --- a/036-hover-in-flutter-web/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - the_basics - - - - - diff --git a/037-advanced-web-navigation/00-starting/.firebaserc b/037-advanced-web-navigation/00-starting/.firebaserc deleted file mode 100644 index a41be430..00000000 --- a/037-advanced-web-navigation/00-starting/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "thebasics-2f123" - } -} diff --git a/037-advanced-web-navigation/00-starting/.gitignore b/037-advanced-web-navigation/00-starting/.gitignore deleted file mode 100644 index 36a616eb..00000000 --- a/037-advanced-web-navigation/00-starting/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Exceptions to above rules. -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/037-advanced-web-navigation/00-starting/.metadata b/037-advanced-web-navigation/00-starting/.metadata deleted file mode 100644 index c17efdcf..00000000 --- a/037-advanced-web-navigation/00-starting/.metadata +++ /dev/null @@ -1,10 +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: 8e0799a657051bf540d98b8aecf9cfa1325f3f71 - channel: master - -project_type: app diff --git a/037-advanced-web-navigation/00-starting/README.md b/037-advanced-web-navigation/00-starting/README.md deleted file mode 100644 index e42c305e..00000000 --- a/037-advanced-web-navigation/00-starting/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# the_basics - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/037-advanced-web-navigation/00-starting/assets/fonts/OpenSans-ExtraBold.ttf b/037-advanced-web-navigation/00-starting/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 67fcf0fb..00000000 Binary files a/037-advanced-web-navigation/00-starting/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/037-advanced-web-navigation/00-starting/assets/fonts/OpenSans-Regular.ttf b/037-advanced-web-navigation/00-starting/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 29bfd35a..00000000 Binary files a/037-advanced-web-navigation/00-starting/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/037-advanced-web-navigation/00-starting/assets/logo.png b/037-advanced-web-navigation/00-starting/assets/logo.png deleted file mode 100644 index bcd4c4b9..00000000 Binary files a/037-advanced-web-navigation/00-starting/assets/logo.png and /dev/null differ diff --git a/037-advanced-web-navigation/00-starting/firebase.json b/037-advanced-web-navigation/00-starting/firebase.json deleted file mode 100644 index 66037326..00000000 --- a/037-advanced-web-navigation/00-starting/firebase.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "hosting": { - "public": "build/web", - "ignore": [ - "firebase.json", - "**/.*", - "**/node_modules/**" - ], - "rewrites": [ - { - "source": "**", - "destination": "/index.html" - } - ] - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/constants/app_colors.dart b/037-advanced-web-navigation/00-starting/lib/constants/app_colors.dart deleted file mode 100644 index 4524aca0..00000000 --- a/037-advanced-web-navigation/00-starting/lib/constants/app_colors.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color primaryColor = Color.fromARGB(255, 31, 229, 146); \ No newline at end of file diff --git a/037-advanced-web-navigation/00-starting/lib/datamodels/episode_item_model.dart b/037-advanced-web-navigation/00-starting/lib/datamodels/episode_item_model.dart deleted file mode 100644 index 397adab3..00000000 --- a/037-advanced-web-navigation/00-starting/lib/datamodels/episode_item_model.dart +++ /dev/null @@ -1,16 +0,0 @@ -class EpisodeItemModel { - final String title; - final double duration; - final String imageUrl; - - EpisodeItemModel({ - this.title, - this.duration, - this.imageUrl, - }); - - EpisodeItemModel.fromJson(Map map) - : title = map['title'], - duration = map['duration'], - imageUrl = map['imageUrl']; -} diff --git a/037-advanced-web-navigation/00-starting/lib/datamodels/navbar_item_model.dart b/037-advanced-web-navigation/00-starting/lib/datamodels/navbar_item_model.dart deleted file mode 100644 index c3b4d632..00000000 --- a/037-advanced-web-navigation/00-starting/lib/datamodels/navbar_item_model.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class NavBarItemModel { - final String title; - final String navigationPath; - final IconData iconData; - - NavBarItemModel({ - this.title, - this.navigationPath, - this.iconData, - }); -} diff --git a/037-advanced-web-navigation/00-starting/lib/datamodels/season_details_model.dart b/037-advanced-web-navigation/00-starting/lib/datamodels/season_details_model.dart deleted file mode 100644 index 5bb623fc..00000000 --- a/037-advanced-web-navigation/00-starting/lib/datamodels/season_details_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class SeasonDetailsModel { - final String title; - final String description; - - SeasonDetailsModel({ - @required this.title, - @required this.description, - }); -} diff --git a/037-advanced-web-navigation/00-starting/lib/extensions/hover_extensions.dart b/037-advanced-web-navigation/00-starting/lib/extensions/hover_extensions.dart deleted file mode 100644 index 33cc115b..00000000 --- a/037-advanced-web-navigation/00-starting/lib/extensions/hover_extensions.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'dart:html' as html; - -import 'package:the_basics/widgets/translate_on_hover.dart'; - -extension HoverExtensions on Widget { - static final appContainer = - html.window.document.getElementById('app-container'); - - Widget get showCursorOnHover { - return MouseRegion( - child: this, // the widget we're using the extension on - onHover: (event) => appContainer.style.cursor = 'pointer', - onExit: (event) => appContainer.style.cursor = 'default', - ); - } - - Widget get moveUpOnHover { - return TranslateOnHover( - child: this, - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/locator.dart b/037-advanced-web-navigation/00-starting/lib/locator.dart deleted file mode 100644 index a0c940fc..00000000 --- a/037-advanced-web-navigation/00-starting/lib/locator.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:the_basics/services/api.dart'; -import 'package:the_basics/services/navigation_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => Api()); -} \ No newline at end of file diff --git a/037-advanced-web-navigation/00-starting/lib/main.dart b/037-advanced-web-navigation/00-starting/lib/main.dart deleted file mode 100644 index 135075f6..00000000 --- a/037-advanced-web-navigation/00-starting/lib/main.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/views/layout_template/layout_template.dart'; - -import 'locator.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - textTheme: Theme.of(context).textTheme.apply(fontFamily: 'Open Sans'), - ), - home: LayoutTemplate(), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/routing/route_names.dart b/037-advanced-web-navigation/00-starting/lib/routing/route_names.dart deleted file mode 100644 index 7db20149..00000000 --- a/037-advanced-web-navigation/00-starting/lib/routing/route_names.dart +++ /dev/null @@ -1,4 +0,0 @@ -const String HomeRoute = 'home'; -const String AboutRoute = 'about'; -const String EpisodesRoute = 'episodes'; -const String EpisodeDetailsRoute = 'episode'; diff --git a/037-advanced-web-navigation/00-starting/lib/routing/router.dart b/037-advanced-web-navigation/00-starting/lib/routing/router.dart deleted file mode 100644 index 1b851e97..00000000 --- a/037-advanced-web-navigation/00-starting/lib/routing/router.dart +++ /dev/null @@ -1,51 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/views/about/about_view.dart'; -import 'package:the_basics/views/episode_details/episode_details.dart'; -import 'package:the_basics/views/episodes/episodes_view.dart'; -import 'package:the_basics/views/home/home_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case HomeRoute: - return _getPageRoute(HomeView(), settings); - case AboutRoute: - return _getPageRoute(AboutView(), settings); - case EpisodesRoute: - return _getPageRoute(EpisodesView(), settings); - case EpisodeDetailsRoute: - return _getPageRoute(EpisodeDetails(), settings); - default: - return _getPageRoute(HomeView(), settings); - } -} - -PageRoute _getPageRoute(Widget child, RouteSettings settings) { - return _FadeRoute(child: child, routeName: settings.name); -} - -class _FadeRoute extends PageRouteBuilder { - final Widget child; - final String routeName; - _FadeRoute({this.child, this.routeName}) - : super( - settings: RouteSettings(name: routeName), - pageBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - ) => - child, - transitionsBuilder: ( - BuildContext context, - Animation animation, - Animation secondaryAnimation, - Widget child, - ) => - FadeTransition( - opacity: animation, - child: child, - ), - ); -} diff --git a/037-advanced-web-navigation/00-starting/lib/services/api.dart b/037-advanced-web-navigation/00-starting/lib/services/api.dart deleted file mode 100644 index dc92b23e..00000000 --- a/037-advanced-web-navigation/00-starting/lib/services/api.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:http/http.dart' as http; -import 'dart:convert'; - -import 'package:the_basics/datamodels/episode_item_model.dart'; - -class Api { - static const String _apiEndpoint = - 'https://us-central1-thebasics-2f123.cloudfunctions.net/thebasics'; - - Future getEpisodes() async { - var response = await http.get('$_apiEndpoint/courseEpisodes'); - - if (response.statusCode == 200) { - var episodes = (json.decode(response.body) as List) - .map((episode) => EpisodeItemModel.fromJson(episode)) - .toList(); - return episodes; - } - - // something wrong happened - return 'Could not fetch the episodes at this time'; - } - - Future getEpisode(int id) async { - var response = await http.get('$_apiEndpoint/episode?id=$id'); - - print( - 'getEpisode | response: ${response.body} statusCode: ${response.statusCode}'); - - if (response.statusCode == 200) { - var episode = EpisodeItemModel.fromJson(json.decode(response.body)); - return episode; - } - - // something wrong happened - return 'Could not fetch episode $id. Make sure it exists'; - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/services/navigation_service.dart b/037-advanced-web-navigation/00-starting/lib/services/navigation_service.dart deleted file mode 100644 index d4a51a00..00000000 --- a/037-advanced-web-navigation/00-starting/lib/services/navigation_service.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - final GlobalKey navigatorKey = GlobalKey(); - - Future navigateTo(String routeName) { - return navigatorKey.currentState.pushNamed(routeName); - } - - void goBack() { - return navigatorKey.currentState.pop(); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/styles/text_styles.dart b/037-advanced-web-navigation/00-starting/lib/styles/text_styles.dart deleted file mode 100644 index de84920b..00000000 --- a/037-advanced-web-navigation/00-starting/lib/styles/text_styles.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -/// Returns the style for a page title based on the [deviceScreenType] passed in. -TextStyle titleTextStyle(DeviceScreenType deviceScreenType) { - double titleSize = deviceScreenType == DeviceScreenType.mobile ? 50 : 80; - return TextStyle( - fontWeight: FontWeight.w800, height: 0.9, fontSize: titleSize); -} - -/// Return the style for description text on a page based on the [deviceScreenType] passed in. -TextStyle descriptionTextStyle(DeviceScreenType deviceScreenType) { - double descriptionSize = - deviceScreenType == DeviceScreenType.mobile ? 16 : 21; - - return TextStyle( - fontSize: descriptionSize, - height: 1.7, - ); -} diff --git a/037-advanced-web-navigation/00-starting/lib/viewmodels/episode_details_view_model.dart b/037-advanced-web-navigation/00-starting/lib/viewmodels/episode_details_view_model.dart deleted file mode 100644 index de3d14b0..00000000 --- a/037-advanced-web-navigation/00-starting/lib/viewmodels/episode_details_view_model.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/api.dart'; - -class EpisodeDetailsViewModel extends ChangeNotifier { - final Api _api = locator(); - - EpisodeItemModel _episode; - - EpisodeItemModel get episode => _episode; - - Future getEpisodeData(int id) async { - var response = await _api.getEpisode(id); - - if (response is String) { - _episode = EpisodeItemModel(title: response); - } else { - _episode = response; - } - - notifyListeners(); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/viewmodels/episode_list_view_model.dart b/037-advanced-web-navigation/00-starting/lib/viewmodels/episode_list_view_model.dart deleted file mode 100644 index e5b5d5a8..00000000 --- a/037-advanced-web-navigation/00-starting/lib/viewmodels/episode_list_view_model.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:flutter/cupertino.dart'; - -class EpisodeListViewModel extends ChangeNotifier {} diff --git a/037-advanced-web-navigation/00-starting/lib/viewmodels/episodes_view_model.dart b/037-advanced-web-navigation/00-starting/lib/viewmodels/episodes_view_model.dart deleted file mode 100644 index e7a17521..00000000 --- a/037-advanced-web-navigation/00-starting/lib/viewmodels/episodes_view_model.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/api.dart'; - -class EpisodesViewModel extends ChangeNotifier { - final _api = locator(); - - List _episodes; - List get episodes => _episodes; - - Future getEpisodes() async { - var episodeResults = await _api.getEpisodes(); - - if (episodeResults is String) { - // show error - } else { - _episodes = episodeResults; - } - - notifyListeners(); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/views/about/about_view.dart b/037-advanced-web-navigation/00-starting/lib/views/about/about_view.dart deleted file mode 100644 index 34741b6f..00000000 --- a/037-advanced-web-navigation/00-starting/lib/views/about/about_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class AboutView extends StatelessWidget { - const AboutView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - color: Colors.red, - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/views/episode_details/episode_details.dart b/037-advanced-web-navigation/00-starting/lib/views/episode_details/episode_details.dart deleted file mode 100644 index 7dca83b9..00000000 --- a/037-advanced-web-navigation/00-starting/lib/views/episode_details/episode_details.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/viewmodels/episode_details_view_model.dart'; - -class EpisodeDetails extends StatelessWidget { - final int id; - const EpisodeDetails({Key key, this.id}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => EpisodeDetailsViewModel(), - onModelReady: (model) => model.getEpisodeData(id), - builder: (context, model, child) => Center( - child: Column( - children: [ - model.episode == null - ? Container() - : SizedBox( - height: 320, - child: Image.network( - model.episode.imageUrl, - fit: BoxFit.cover, - ), - ), - model.episode == null - ? CircularProgressIndicator() - : Text( - model.episode.title, - style: TextStyle(fontSize: 60), - ), - ], - ), - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/views/episodes/episodes_view.dart b/037-advanced-web-navigation/00-starting/lib/views/episodes/episodes_view.dart deleted file mode 100644 index 5bed4225..00000000 --- a/037-advanced-web-navigation/00-starting/lib/views/episodes/episodes_view.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/viewmodels/episodes_view_model.dart'; -import 'package:the_basics/widgets/episodes_list/episodes_list.dart'; -import 'package:the_basics/widgets/season_details/season_details.dart'; - -class EpisodesView extends StatelessWidget { - const EpisodesView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => EpisodesViewModel(), - onModelReady: (model) => model.getEpisodes(), - builder: (context, model, child) => SingleChildScrollView( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - SizedBox( - height: 100, - ), - SeasonDetails( - details: SeasonDetailsModel( - title: 'SEASON 1', - description: - 'This season covers the absolute basics of Flutter Web Dev to get us up and running with a basic web app.', - ), - ), - SizedBox( - height: 50, - ), - model.episodes == null - ? CircularProgressIndicator() - : EpisodesList(episodes: model.episodes), - ], - )), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/views/home/home_content_desktop.dart b/037-advanced-web-navigation/00-starting/lib/views/home/home_content_desktop.dart deleted file mode 100644 index 4fab7a21..00000000 --- a/037-advanced-web-navigation/00-starting/lib/views/home/home_content_desktop.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentDesktop extends StatelessWidget { - const HomeContentDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Row( - children: [ - CourseDetails(), - Expanded( - child: Center( - child: CallToAction('Join Course'), - ), - ) - ], - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/views/home/home_content_mobile.dart b/037-advanced-web-navigation/00-starting/lib/views/home/home_content_mobile.dart deleted file mode 100644 index 028c8d38..00000000 --- a/037-advanced-web-navigation/00-starting/lib/views/home/home_content_mobile.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action.dart'; -import 'package:the_basics/widgets/course_details/course_details.dart'; - -class HomeContentMobile extends StatelessWidget { - const HomeContentMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - CourseDetails(), - SizedBox( - height: 100, - ), - CallToAction('Join Course'), - ], - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/views/home/home_view.dart b/037-advanced-web-navigation/00-starting/lib/views/home/home_view.dart deleted file mode 100644 index a138243d..00000000 --- a/037-advanced-web-navigation/00-starting/lib/views/home/home_view.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/views/home/home_content_desktop.dart'; -import 'package:the_basics/views/home/home_content_mobile.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: HomeContentMobile(), - desktop: HomeContentDesktop(), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/views/layout_template/layout_template.dart b/037-advanced-web-navigation/00-starting/lib/views/layout_template/layout_template.dart deleted file mode 100644 index b6d5030d..00000000 --- a/037-advanced-web-navigation/00-starting/lib/views/layout_template/layout_template.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/routing/router.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/centered_view/centered_view.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer.dart'; - -class LayoutTemplate extends StatelessWidget { - const LayoutTemplate({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Scaffold( - drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile - ? NavigationDrawer() - : null, - backgroundColor: Colors.white, - body: CenteredView( - child: Column( - children: [ - NavigationBar(), - Expanded( - child: Navigator( - key: locator().navigatorKey, - onGenerateRoute: generateRoute, - initialRoute: HomeRoute, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action.dart b/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action.dart deleted file mode 100644 index 13ceb078..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_mobile.dart'; -import 'package:the_basics/widgets/call_to_action/call_to_action_tablet_desktop.dart'; -import 'package:the_basics/extensions/hover_extensions.dart'; - -class CallToAction extends StatelessWidget { - final String title; - CallToAction(this.title); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: CallToActionMobile(title), - tablet: CallToActionTabletDesktop(title), - ).showCursorOnHover.moveUpOnHover; - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action_mobile.dart b/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action_mobile.dart deleted file mode 100644 index d2455218..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action_mobile.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionMobile extends StatelessWidget { - final String title; - const CallToActionMobile(this.title); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - alignment: Alignment.center, - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart b/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart deleted file mode 100644 index 0ea18c80..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/call_to_action/call_to_action_tablet_desktop.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class CallToActionTabletDesktop extends StatelessWidget { - final String title; - const CallToActionTabletDesktop(this.title); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 60, vertical: 15), - child: Text( - title, - style: TextStyle( - fontSize: 18, - fontWeight: FontWeight.w800, - color: Colors.white, - ), - ), - decoration: BoxDecoration( - color: primaryColor, - borderRadius: BorderRadius.circular(5), - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/centered_view/centered_view.dart b/037-advanced-web-navigation/00-starting/lib/widgets/centered_view/centered_view.dart deleted file mode 100644 index 1aed138b..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/centered_view/centered_view.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class CenteredView extends StatelessWidget { - final Widget child; - const CenteredView({Key key, this.child}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(horizontal: 70, vertical: 60), - alignment: Alignment.topCenter, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 1200), - child: child, - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/course_details/course_details.dart b/037-advanced-web-navigation/00-starting/lib/widgets/course_details/course_details.dart deleted file mode 100644 index 299ed635..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/course_details/course_details.dart +++ /dev/null @@ -1,42 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class CourseDetails extends StatelessWidget { - const CourseDetails({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ResponsiveBuilder( - builder: (context, sizingInformation) { - var textAlignment = - sizingInformation.deviceScreenType == DeviceScreenType.desktop - ? TextAlign.left - : TextAlign.center; - - return Container( - width: 600, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - 'FLUTTER WEB.\nTHE BASICS', - style: titleTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ), - SizedBox( - height: 30, - ), - Text( - 'In this course we will go over the basics of using Flutter Web for website development. Topics will include Responsive Layout, Deploying, Font Changes, Hover Functionality, Modals and more.', - style: descriptionTextStyle(sizingInformation.deviceScreenType), - textAlign: textAlignment, - ) - ], - ), - ); - }, - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/episodes_list/episode_item.dart b/037-advanced-web-navigation/00-starting/lib/widgets/episodes_list/episode_item.dart deleted file mode 100644 index de43ac02..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/episodes_list/episode_item.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; -import 'package:the_basics/extensions/hover_extensions.dart'; - -class EpisodeItem extends StatelessWidget { - final EpisodeItemModel model; - const EpisodeItem({ - Key key, - this.model, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Card( - color: Colors.white, - elevation: 2, - child: SizedBox( - width: 360, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: 180, - child: Image.network(model.imageUrl, fit: BoxFit.cover,), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15.0, - vertical: 20, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - model.title, - style: TextStyle( - fontWeight: FontWeight.w700, - fontSize: 14, - ), - softWrap: true, - ), - Text( - '${model.duration} minutes', - style: TextStyle(fontSize: 10), - ) - ], - ), - ), - ], - ), - ), - ).showCursorOnHover; - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/episodes_list/episodes_list.dart b/037-advanced-web-navigation/00-starting/lib/widgets/episodes_list/episodes_list.dart deleted file mode 100644 index 841123ab..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/episodes_list/episodes_list.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/episode_item_model.dart'; -import 'package:the_basics/viewmodels/episode_list_view_model.dart'; - -import 'episode_item.dart'; - -class EpisodesList extends StatelessWidget { - final List episodes; - EpisodesList({this.episodes}); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => EpisodeListViewModel(), - builder: (context, model, child) => Wrap( - spacing: 30, - runSpacing: 30, - children: [ - ...episodes.map((episode) => EpisodeItem(model: episode)).toList() - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item.dart deleted file mode 100644 index 38a23432..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; -import 'package:the_basics/locator.dart'; -import 'package:the_basics/services/navigation_service.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_desktop.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item_mobile.dart'; -import 'package:the_basics/extensions/hover_extensions.dart'; - -class NavBarItem extends StatelessWidget { - final String title; - final String navigationPath; - final IconData icon; - const NavBarItem(this.title, this.navigationPath, {this.icon}); - - @override - Widget build(BuildContext context) { - var model = NavBarItemModel( - title: title, - navigationPath: navigationPath, - iconData: icon, - ); - return GestureDetector( - onTap: () { - // DON'T EVER USE A SERVICE DIRECTLY IN THE UI TO CHANGE ANY KIND OF STATE - // SERVICES SHOULD ONLY BE USED FROM A VIEWMODEL - locator().navigateTo(navigationPath); - }, - child: Provider.value( - value: model, - child: ScreenTypeLayout( - tablet: NavBarItemTabletDesktop(), - mobile: NavBarItemMobile(), - ).showCursorOnHover.moveUpOnHover, - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item_desktop.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item_desktop.dart deleted file mode 100644 index 49dd9b81..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item_desktop.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemTabletDesktop extends ViewModelWidget { - @override - Widget build(BuildContext context, NavBarItemModel model) { - return Text( - model.title, - style: TextStyle(fontSize: 18), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item_mobile.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item_mobile.dart deleted file mode 100644 index beee7c38..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navbar_item/navbar_item_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:the_basics/datamodels/navbar_item_model.dart'; - -class NavBarItemMobile extends ViewModelWidget { - @override - Widget build(BuildContext context, NavBarItemModel model) { - return Padding( - padding: const EdgeInsets.only(left: 30, top: 60), - child: Row( - children: [ - Icon(model.iconData), - SizedBox( - width: 30, - ), - Text( - model.title, - style: TextStyle(fontSize: 18), - ) - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navbar_logo.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navbar_logo.dart deleted file mode 100644 index 483fe20f..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navbar_logo.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavBarLogo extends StatelessWidget { - const NavBarLogo({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return SizedBox( - height: 80, - width: 150, - child: Image.asset('assets/logo.png'), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar.dart deleted file mode 100644 index a09d1e34..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_tablet_desktop.dart'; -import 'package:the_basics/widgets/navigation_bar/navigation_bar_mobile.dart'; -import 'package:responsive_builder/responsive_builder.dart'; - -class NavigationBar extends StatelessWidget { - const NavigationBar({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ScreenTypeLayout( - mobile: NavigationBarMobile(), - tablet: NavigationBarTabletDesktop(), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar_mobile.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar_mobile.dart deleted file mode 100644 index 387f852c..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar_mobile.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/widgets/navigation_bar/navbar_logo.dart'; - -class NavigationBarMobile extends StatelessWidget { - const NavigationBarMobile({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 80, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - IconButton( - icon: Icon(Icons.menu), - onPressed: () {}, - ), - NavBarLogo() - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart deleted file mode 100644 index 6f622c31..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_bar/navigation_bar_tablet_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; - -import 'navbar_logo.dart'; - -class NavigationBarTabletDesktop extends StatelessWidget { - const NavigationBarTabletDesktop({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 100, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - NavBarLogo(), - Row( - mainAxisSize: MainAxisSize.min, - children: [ - NavBarItem('Episodes', EpisodesRoute), - SizedBox( - width: 60, - ), - NavBarItem('About', AboutRoute), - ], - ) - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_drawer/navigation_drawer.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navigation_drawer/navigation_drawer.dart deleted file mode 100644 index 257d4153..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_drawer/navigation_drawer.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/routing/route_names.dart'; -import 'package:the_basics/widgets/navbar_item/navbar_item.dart'; -import 'package:the_basics/widgets/navigation_drawer/navigation_drawer_header.dart'; - -class NavigationDrawer extends StatelessWidget { - const NavigationDrawer({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - width: 300, - decoration: BoxDecoration( - color: Colors.white, - boxShadow: [ - BoxShadow(color: Colors.black12, blurRadius: 16), - ], - ), - child: Column( - children: [ - NavigationDrawerHeader(), - // BONUS: Combine the UI for this widget with the NavBarItem and make it responsive. - // The UI for the current DrawerItem shows when it's in mobile, else it shows the NavBarItem ui. - NavBarItem( - 'Episodes', - EpisodesRoute, - icon: Icons.videocam, - ), - NavBarItem( - 'About', - AboutRoute, - icon: Icons.help, - ), - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_drawer/navigation_drawer_header.dart b/037-advanced-web-navigation/00-starting/lib/widgets/navigation_drawer/navigation_drawer_header.dart deleted file mode 100644 index 0b96e2af..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/navigation_drawer/navigation_drawer_header.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:the_basics/constants/app_colors.dart'; - -class NavigationDrawerHeader extends StatelessWidget { - const NavigationDrawerHeader({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 150, - color: primaryColor, - alignment: Alignment.center, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - 'SKILL UP NOW', - style: TextStyle( - fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white), - ), - Text( - 'TAP HERE', - style: TextStyle( - color: Colors.white, - ), - ) - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details.dart b/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details.dart deleted file mode 100644 index 7b4b5a0f..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/widgets/season_details/season_details_desktop.dart'; -import 'package:the_basics/widgets/season_details/season_details_mobile.dart'; - -class SeasonDetails extends StatelessWidget { - final SeasonDetailsModel details; - const SeasonDetails({Key key, this.details}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Provider.value( - value: details, - child: ScreenTypeLayout( - desktop: SeasonDetailsDesktop(), - mobile: SeasonDetailsMobile(), - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details_desktop.dart b/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details_desktop.dart deleted file mode 100644 index b98619a8..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details_desktop.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsDesktop extends ViewModelWidget { - @override - Widget build(BuildContext context, SeasonDetailsModel details) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - width: 50, - ), - Expanded( - child: Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ) - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details_mobile.dart b/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details_mobile.dart deleted file mode 100644 index f6d5ec3d..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/season_details/season_details_mobile.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:responsive_builder/responsive_builder.dart'; -import 'package:the_basics/datamodels/season_details_model.dart'; -import 'package:the_basics/styles/text_styles.dart'; - -class SeasonDetailsMobile extends ViewModelWidget { - @override - Widget build(BuildContext context, SeasonDetailsModel details) { - return ResponsiveBuilder( - builder: (context, sizingInformation) => Column( - children: [ - Text( - details.title, - style: titleTextStyle(sizingInformation.deviceScreenType), - ), - SizedBox( - height: 50, - ), - Text( - details.description, - style: descriptionTextStyle(sizingInformation.deviceScreenType), - ), - ], - ), - ); - } -} diff --git a/037-advanced-web-navigation/00-starting/lib/widgets/translate_on_hover.dart b/037-advanced-web-navigation/00-starting/lib/widgets/translate_on_hover.dart deleted file mode 100644 index c966057f..00000000 --- a/037-advanced-web-navigation/00-starting/lib/widgets/translate_on_hover.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:flutter/material.dart'; - -class TranslateOnHover extends StatefulWidget { - final Widget child; - TranslateOnHover({Key key, this.child}) : super(key: key); - - @override - _TranslateOnHoverState createState() => _TranslateOnHoverState(); -} - -class _TranslateOnHoverState extends State { - final nonHoverTransform = Matrix4.identity(); - final hoverTransform = Matrix4.identity()..translate(0, -5, 0); - - bool _hovering = false; - - @override - Widget build(BuildContext context) { - return MouseRegion( - onEnter: (e) => _mouseEnter(true), - onExit: (e) => _mouseEnter(false), - child: AnimatedContainer( - duration: const Duration(milliseconds: 200), - child: widget.child, - transform: _hovering ? hoverTransform : nonHoverTransform, - ), - ); - } - - void _mouseEnter(bool hovering) { - setState(() { - _hovering = hovering; - }); - } -} diff --git a/037-advanced-web-navigation/00-starting/pubspec.lock b/037-advanced-web-navigation/00-starting/pubspec.lock deleted file mode 100644 index 379da8e7..00000000 --- a/037-advanced-web-navigation/00-starting/pubspec.lock +++ /dev/null @@ -1,210 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - responsive_builder: - dependency: "direct main" - description: - name: responsive_builder - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/037-advanced-web-navigation/00-starting/pubspec.yaml b/037-advanced-web-navigation/00-starting/pubspec.yaml deleted file mode 100644 index a6b581b1..00000000 --- a/037-advanced-web-navigation/00-starting/pubspec.yaml +++ /dev/null @@ -1,78 +0,0 @@ -name: the_basics -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.6.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - responsive_builder: ^0.2.0+2 - get_it: ^4.0.2 - stacked: ^1.6.0 - provider: ^4.1.3 - http: ^0.12.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/logo.png - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/037-advanced-web-navigation/00-starting/test/widget_test.dart b/037-advanced-web-navigation/00-starting/test/widget_test.dart deleted file mode 100644 index b9e0d165..00000000 --- a/037-advanced-web-navigation/00-starting/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:the_basics/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/037-advanced-web-navigation/00-starting/web/index.html b/037-advanced-web-navigation/00-starting/web/index.html deleted file mode 100644 index 64fae6cf..00000000 --- a/037-advanced-web-navigation/00-starting/web/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - the_basics - - - - - diff --git a/038-firebase-authentication/00-starting/.gitignore b/038-firebase-authentication/00-starting/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/038-firebase-authentication/00-starting/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/038-firebase-authentication/00-starting/.metadata b/038-firebase-authentication/00-starting/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/038-firebase-authentication/00-starting/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/038-firebase-authentication/00-starting/README.md b/038-firebase-authentication/00-starting/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Bold.ttf b/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-ExtraBold.ttf b/038-firebase-authentication/00-starting/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Light.ttf b/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Regular.ttf b/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/038-firebase-authentication/00-starting/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/038-firebase-authentication/00-starting/assets/images/icon_large.png b/038-firebase-authentication/00-starting/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/038-firebase-authentication/00-starting/assets/images/icon_large.png and /dev/null differ diff --git a/038-firebase-authentication/00-starting/assets/images/title.png b/038-firebase-authentication/00-starting/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/038-firebase-authentication/00-starting/assets/images/title.png and /dev/null differ diff --git a/038-firebase-authentication/00-starting/lib/constants/route_names.dart b/038-firebase-authentication/00-starting/lib/constants/route_names.dart deleted file mode 100644 index 6d50d29f..00000000 --- a/038-firebase-authentication/00-starting/lib/constants/route_names.dart +++ /dev/null @@ -1,4 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -// Generate the views here \ No newline at end of file diff --git a/038-firebase-authentication/00-starting/lib/locator.dart b/038-firebase-authentication/00-starting/lib/locator.dart deleted file mode 100644 index 9d251d8f..00000000 --- a/038-firebase-authentication/00-starting/lib/locator.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); -} diff --git a/038-firebase-authentication/00-starting/lib/main.dart b/038-firebase-authentication/00-starting/lib/main.dart deleted file mode 100644 index 7fa09b09..00000000 --- a/038-firebase-authentication/00-starting/lib/main.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:compound/ui/views/signup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color.fromARGB(255, 9, 202, 172), - backgroundColor: Color.fromARGB(255, 26, 27, 30), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: SignUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/managers/dialog_manager.dart b/038-firebase-authentication/00-starting/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/038-firebase-authentication/00-starting/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/038-firebase-authentication/00-starting/lib/models/dialog_models.dart b/038-firebase-authentication/00-starting/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/038-firebase-authentication/00-starting/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/038-firebase-authentication/00-starting/lib/services/dialog_service.dart b/038-firebase-authentication/00-starting/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/038-firebase-authentication/00-starting/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/038-firebase-authentication/00-starting/lib/services/navigation_service.dart b/038-firebase-authentication/00-starting/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/038-firebase-authentication/00-starting/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/router.dart b/038-firebase-authentication/00-starting/lib/ui/router.dart deleted file mode 100644 index 6586e1bc..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/router.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/038-firebase-authentication/00-starting/lib/ui/shared/app_colors.dart b/038-firebase-authentication/00-starting/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/038-firebase-authentication/00-starting/lib/ui/shared/shared_styles.dart b/038-firebase-authentication/00-starting/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/038-firebase-authentication/00-starting/lib/ui/shared/ui_helpers.dart b/038-firebase-authentication/00-starting/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/038-firebase-authentication/00-starting/lib/ui/views/base_widget.dart b/038-firebase-authentication/00-starting/lib/ui/views/base_widget.dart deleted file mode 100644 index cd946013..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/views/base_widget.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:provider/provider.dart'; - -class BaseWidget extends StatefulWidget { - final Widget Function(BuildContext context, T model, Widget child) builder; - final Function(T) onModelReady; - final T model; - final Widget child; - - BaseWidget({this.builder, this.onModelReady, this.model, this.child}); - - @override - _BaseWidgetState createState() => _BaseWidgetState(); -} - -class _BaseWidgetState extends State> { - T _model; - - @override - void initState() { - _model = widget.model; - - if (widget.onModelReady != null) { - widget.onModelReady(_model); - } - - super.initState(); - } - - @override - Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (context) => _model, - child: Consumer( - child: widget.child, - builder: widget.builder ?? (context, model, child) => child, - )); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/views/home_view.dart b/038-firebase-authentication/00-starting/lib/ui/views/home_view.dart deleted file mode 100644 index fc493a33..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/views/home_view.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Center( - child: Text('Home'), - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/views/login_view.dart b/038-firebase-authentication/00-starting/lib/ui/views/login_view.dart deleted file mode 100644 index b649189c..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/views/login_view.dart +++ /dev/null @@ -1,65 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - onPressed: () { - // TODO: Perform firebase login here - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - // TODO: Handle navigation - }, - ) - ], - ), - )), - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/views/signup_view.dart b/038-firebase-authentication/00-starting/lib/ui/views/signup_view.dart deleted file mode 100644 index 93732602..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - // TODO: Add additional user data here to save (episode 2) - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - onPressed: () { - // TODO: Perform firebase login here - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/widgets/busy_button.dart b/038-firebase-authentication/00-starting/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/widgets/busy_overlay.dart b/038-firebase-authentication/00-starting/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/widgets/input_field.dart b/038-firebase-authentication/00-starting/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/widgets/note_text.dart b/038-firebase-authentication/00-starting/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/ui/widgets/text_link.dart b/038-firebase-authentication/00-starting/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/038-firebase-authentication/00-starting/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/038-firebase-authentication/00-starting/lib/viewmodels/base_model.dart b/038-firebase-authentication/00-starting/lib/viewmodels/base_model.dart deleted file mode 100644 index de51e4c0..00000000 --- a/038-firebase-authentication/00-starting/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/038-firebase-authentication/00-starting/lib/viewmodels/login_view_model.dart b/038-firebase-authentication/00-starting/lib/viewmodels/login_view_model.dart deleted file mode 100644 index 8ab68739..00000000 --- a/038-firebase-authentication/00-starting/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'base_model.dart'; -class LoginViewModel extends BaseModel { -} \ No newline at end of file diff --git a/038-firebase-authentication/00-starting/lib/viewmodels/signup_view_model.dart b/038-firebase-authentication/00-starting/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 1bc9af51..00000000 --- a/038-firebase-authentication/00-starting/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'base_model.dart'; -class SignUpViewModel extends BaseModel { -} \ No newline at end of file diff --git a/038-firebase-authentication/00-starting/pubspec.lock b/038-firebase-authentication/00-starting/pubspec.lock deleted file mode 100644 index 89c7779f..00000000 --- a/038-firebase-authentication/00-starting/pubspec.lock +++ /dev/null @@ -1,224 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0" diff --git a/038-firebase-authentication/00-starting/pubspec.yaml b/038-firebase-authentication/00-starting/pubspec.yaml deleted file mode 100644 index c52a70b5..00000000 --- a/038-firebase-authentication/00-starting/pubspec.yaml +++ /dev/null @@ -1,81 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/038-firebase-authentication/01-final/.flutter-plugins-dependencies b/038-firebase-authentication/01-final/.flutter-plugins-dependencies deleted file mode 100644 index 0140a171..00000000 --- a/038-firebase-authentication/01-final/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"android":[{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"macos":[{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]}],"date_created":"2020-06-18 21:48:57.380605","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/038-firebase-authentication/01-final/.gitignore b/038-firebase-authentication/01-final/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/038-firebase-authentication/01-final/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/038-firebase-authentication/01-final/.metadata b/038-firebase-authentication/01-final/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/038-firebase-authentication/01-final/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/038-firebase-authentication/01-final/README.md b/038-firebase-authentication/01-final/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/038-firebase-authentication/01-final/assets/fonts/OpenSans-Bold.ttf b/038-firebase-authentication/01-final/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/038-firebase-authentication/01-final/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/038-firebase-authentication/01-final/assets/fonts/OpenSans-ExtraBold.ttf b/038-firebase-authentication/01-final/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/038-firebase-authentication/01-final/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/038-firebase-authentication/01-final/assets/fonts/OpenSans-Light.ttf b/038-firebase-authentication/01-final/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/038-firebase-authentication/01-final/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/038-firebase-authentication/01-final/assets/fonts/OpenSans-Regular.ttf b/038-firebase-authentication/01-final/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/038-firebase-authentication/01-final/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/038-firebase-authentication/01-final/assets/images/icon_large.png b/038-firebase-authentication/01-final/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/038-firebase-authentication/01-final/assets/images/icon_large.png and /dev/null differ diff --git a/038-firebase-authentication/01-final/assets/images/title.png b/038-firebase-authentication/01-final/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/038-firebase-authentication/01-final/assets/images/title.png and /dev/null differ diff --git a/038-firebase-authentication/01-final/lib/constants/route_names.dart b/038-firebase-authentication/01-final/lib/constants/route_names.dart deleted file mode 100644 index 6d50d29f..00000000 --- a/038-firebase-authentication/01-final/lib/constants/route_names.dart +++ /dev/null @@ -1,4 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -// Generate the views here \ No newline at end of file diff --git a/038-firebase-authentication/01-final/lib/locator.dart b/038-firebase-authentication/01-final/lib/locator.dart deleted file mode 100644 index cfc51f8c..00000000 --- a/038-firebase-authentication/01-final/lib/locator.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:compound/services/authentication_service.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); -} diff --git a/038-firebase-authentication/01-final/lib/main.dart b/038-firebase-authentication/01-final/lib/main.dart deleted file mode 100644 index 302f7b1e..00000000 --- a/038-firebase-authentication/01-final/lib/main.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color.fromARGB(255, 9, 202, 172), - backgroundColor: Color.fromARGB(255, 26, 27, 30), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: LoginView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/managers/dialog_manager.dart b/038-firebase-authentication/01-final/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/038-firebase-authentication/01-final/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/038-firebase-authentication/01-final/lib/models/dialog_models.dart b/038-firebase-authentication/01-final/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/038-firebase-authentication/01-final/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/038-firebase-authentication/01-final/lib/services/authentication_service.dart b/038-firebase-authentication/01-final/lib/services/authentication_service.dart deleted file mode 100644 index 31e39fe0..00000000 --- a/038-firebase-authentication/01-final/lib/services/authentication_service.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var user = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - return user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - return authResult.user != null; - } catch (e) { - return e.message; - } - } -} diff --git a/038-firebase-authentication/01-final/lib/services/dialog_service.dart b/038-firebase-authentication/01-final/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/038-firebase-authentication/01-final/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/038-firebase-authentication/01-final/lib/services/navigation_service.dart b/038-firebase-authentication/01-final/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/038-firebase-authentication/01-final/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/router.dart b/038-firebase-authentication/01-final/lib/ui/router.dart deleted file mode 100644 index 6586e1bc..00000000 --- a/038-firebase-authentication/01-final/lib/ui/router.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/038-firebase-authentication/01-final/lib/ui/shared/app_colors.dart b/038-firebase-authentication/01-final/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/038-firebase-authentication/01-final/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/038-firebase-authentication/01-final/lib/ui/shared/shared_styles.dart b/038-firebase-authentication/01-final/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/038-firebase-authentication/01-final/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/038-firebase-authentication/01-final/lib/ui/shared/ui_helpers.dart b/038-firebase-authentication/01-final/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/038-firebase-authentication/01-final/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/038-firebase-authentication/01-final/lib/ui/views/home_view.dart b/038-firebase-authentication/01-final/lib/ui/views/home_view.dart deleted file mode 100644 index 0a2cb0c7..00000000 --- a/038-firebase-authentication/01-final/lib/ui/views/home_view.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Text('Home'), - ), - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/views/login_view.dart b/038-firebase-authentication/01-final/lib/ui/views/login_view.dart deleted file mode 100644 index f7a138bc..00000000 --- a/038-firebase-authentication/01-final/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - // TODO: Handle navigation - }, - ) - ], - ), - )), - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/views/signup_view.dart b/038-firebase-authentication/01-final/lib/ui/views/signup_view.dart deleted file mode 100644 index d1760fe5..00000000 --- a/038-firebase-authentication/01-final/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - // TODO: Add additional user data here to save (episode 2) - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/widgets/busy_button.dart b/038-firebase-authentication/01-final/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/038-firebase-authentication/01-final/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/widgets/busy_overlay.dart b/038-firebase-authentication/01-final/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/038-firebase-authentication/01-final/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/widgets/expansion_list.dart b/038-firebase-authentication/01-final/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index 947c6d15..00000000 --- a/038-firebase-authentication/01-final/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(T) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/widgets/input_field.dart b/038-firebase-authentication/01-final/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/038-firebase-authentication/01-final/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/widgets/note_text.dart b/038-firebase-authentication/01-final/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/038-firebase-authentication/01-final/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/ui/widgets/text_link.dart b/038-firebase-authentication/01-final/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/038-firebase-authentication/01-final/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/038-firebase-authentication/01-final/lib/viewmodels/base_model.dart b/038-firebase-authentication/01-final/lib/viewmodels/base_model.dart deleted file mode 100644 index de51e4c0..00000000 --- a/038-firebase-authentication/01-final/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/038-firebase-authentication/01-final/lib/viewmodels/login_view_model.dart b/038-firebase-authentication/01-final/lib/viewmodels/login_view_model.dart deleted file mode 100644 index d0ee0b97..00000000 --- a/038-firebase-authentication/01-final/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } -} diff --git a/038-firebase-authentication/01-final/lib/viewmodels/signup_view_model.dart b/038-firebase-authentication/01-final/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 70a41c5a..00000000 --- a/038-firebase-authentication/01-final/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future signUp({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/038-firebase-authentication/01-final/pubspec.lock b/038-firebase-authentication/01-final/pubspec.lock deleted file mode 100644 index 27f74ba8..00000000 --- a/038-firebase-authentication/01-final/pubspec.lock +++ /dev/null @@ -1,299 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - firebase: - dependency: transitive - description: - name: firebase - url: "https://pub.dartlang.org" - source: hosted - version: "7.2.0" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/038-firebase-authentication/01-final/pubspec.yaml b/038-firebase-authentication/01-final/pubspec.yaml deleted file mode 100644 index 7b05aba9..00000000 --- a/038-firebase-authentication/01-final/pubspec.yaml +++ /dev/null @@ -1,82 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ^0.16.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/039-firebase-custom-start-user-profile/.flutter-plugins-dependencies b/039-firebase-custom-start-user-profile/.flutter-plugins-dependencies deleted file mode 100644 index 4a161803..00000000 --- a/039-firebase-custom-start-user-profile/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]}],"date_created":"2020-06-18 21:48:51.345177","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/039-firebase-custom-start-user-profile/.gitignore b/039-firebase-custom-start-user-profile/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/039-firebase-custom-start-user-profile/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/039-firebase-custom-start-user-profile/.metadata b/039-firebase-custom-start-user-profile/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/039-firebase-custom-start-user-profile/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/039-firebase-custom-start-user-profile/README.md b/039-firebase-custom-start-user-profile/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Bold.ttf b/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-ExtraBold.ttf b/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Light.ttf b/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Regular.ttf b/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/039-firebase-custom-start-user-profile/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/039-firebase-custom-start-user-profile/assets/images/icon_large.png b/039-firebase-custom-start-user-profile/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/039-firebase-custom-start-user-profile/assets/images/icon_large.png and /dev/null differ diff --git a/039-firebase-custom-start-user-profile/assets/images/title.png b/039-firebase-custom-start-user-profile/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/039-firebase-custom-start-user-profile/assets/images/title.png and /dev/null differ diff --git a/039-firebase-custom-start-user-profile/lib/constants/route_names.dart b/039-firebase-custom-start-user-profile/lib/constants/route_names.dart deleted file mode 100644 index 6d50d29f..00000000 --- a/039-firebase-custom-start-user-profile/lib/constants/route_names.dart +++ /dev/null @@ -1,4 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -// Generate the views here \ No newline at end of file diff --git a/039-firebase-custom-start-user-profile/lib/locator.dart b/039-firebase-custom-start-user-profile/lib/locator.dart deleted file mode 100644 index ab8fe4a0..00000000 --- a/039-firebase-custom-start-user-profile/lib/locator.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); -} diff --git a/039-firebase-custom-start-user-profile/lib/main.dart b/039-firebase-custom-start-user-profile/lib/main.dart deleted file mode 100644 index ea7b0877..00000000 --- a/039-firebase-custom-start-user-profile/lib/main.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color.fromARGB(255, 9, 202, 172), - backgroundColor: Color.fromARGB(255, 26, 27, 30), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/managers/dialog_manager.dart b/039-firebase-custom-start-user-profile/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/039-firebase-custom-start-user-profile/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/models/dialog_models.dart b/039-firebase-custom-start-user-profile/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/039-firebase-custom-start-user-profile/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/039-firebase-custom-start-user-profile/lib/models/user.dart b/039-firebase-custom-start-user-profile/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/039-firebase-custom-start-user-profile/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/039-firebase-custom-start-user-profile/lib/services/authentication_service.dart b/039-firebase-custom-start-user-profile/lib/services/authentication_service.dart deleted file mode 100644 index d4edeb14..00000000 --- a/039-firebase-custom-start-user-profile/lib/services/authentication_service.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - } - } -} diff --git a/039-firebase-custom-start-user-profile/lib/services/dialog_service.dart b/039-firebase-custom-start-user-profile/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/039-firebase-custom-start-user-profile/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/039-firebase-custom-start-user-profile/lib/services/firestore_service.dart b/039-firebase-custom-start-user-profile/lib/services/firestore_service.dart deleted file mode 100644 index 96ae1b91..00000000 --- a/039-firebase-custom-start-user-profile/lib/services/firestore_service.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/user.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - return e.message; - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - return e.message; - } - } -} diff --git a/039-firebase-custom-start-user-profile/lib/services/navigation_service.dart b/039-firebase-custom-start-user-profile/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/039-firebase-custom-start-user-profile/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/router.dart b/039-firebase-custom-start-user-profile/lib/ui/router.dart deleted file mode 100644 index 6586e1bc..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/router.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/shared/app_colors.dart b/039-firebase-custom-start-user-profile/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/039-firebase-custom-start-user-profile/lib/ui/shared/shared_styles.dart b/039-firebase-custom-start-user-profile/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/039-firebase-custom-start-user-profile/lib/ui/shared/ui_helpers.dart b/039-firebase-custom-start-user-profile/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/039-firebase-custom-start-user-profile/lib/ui/views/home_view.dart b/039-firebase-custom-start-user-profile/lib/ui/views/home_view.dart deleted file mode 100644 index 0a2cb0c7..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/views/home_view.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: Center( - child: Text('Home'), - ), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/views/login_view.dart b/039-firebase-custom-start-user-profile/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/views/signup_view.dart b/039-firebase-custom-start-user-profile/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/views/startup_view.dart b/039-firebase-custom-start-user-profile/lib/ui/views/startup_view.dart deleted file mode 100644 index d306f357..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Color(0xff19c7c1), - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/widgets/busy_button.dart b/039-firebase-custom-start-user-profile/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/widgets/busy_overlay.dart b/039-firebase-custom-start-user-profile/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/widgets/expansion_list.dart b/039-firebase-custom-start-user-profile/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/widgets/input_field.dart b/039-firebase-custom-start-user-profile/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/widgets/note_text.dart b/039-firebase-custom-start-user-profile/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/ui/widgets/text_link.dart b/039-firebase-custom-start-user-profile/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/039-firebase-custom-start-user-profile/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/viewmodels/base_model.dart b/039-firebase-custom-start-user-profile/lib/viewmodels/base_model.dart deleted file mode 100644 index de51e4c0..00000000 --- a/039-firebase-custom-start-user-profile/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/viewmodels/login_view_model.dart b/039-firebase-custom-start-user-profile/lib/viewmodels/login_view_model.dart deleted file mode 100644 index c3473a10..00000000 --- a/039-firebase-custom-start-user-profile/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/039-firebase-custom-start-user-profile/lib/viewmodels/signup_view_model.dart b/039-firebase-custom-start-user-profile/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 25952a7f..00000000 --- a/039-firebase-custom-start-user-profile/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/039-firebase-custom-start-user-profile/lib/viewmodels/startup_view_model.dart b/039-firebase-custom-start-user-profile/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 45d3e880..00000000 --- a/039-firebase-custom-start-user-profile/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - - Future handleStartUpLogic() async { - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/039-firebase-custom-start-user-profile/pubspec.lock b/039-firebase-custom-start-user-profile/pubspec.lock deleted file mode 100644 index 98cbfe83..00000000 --- a/039-firebase-custom-start-user-profile/pubspec.lock +++ /dev/null @@ -1,320 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.6" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - firebase: - dependency: transitive - description: - name: firebase - url: "https://pub.dartlang.org" - source: hosted - version: "7.2.0" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/039-firebase-custom-start-user-profile/pubspec.yaml b/039-firebase-custom-start-user-profile/pubspec.yaml deleted file mode 100644 index 4931eb8c..00000000 --- a/039-firebase-custom-start-user-profile/pubspec.yaml +++ /dev/null @@ -1,83 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ^0.16.1 - cloud_firestore: ^0.13.6 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/040-firestore-crud/00-starting/.flutter-plugins-dependencies b/040-firestore-crud/00-starting/.flutter-plugins-dependencies deleted file mode 100644 index cf4ab8c6..00000000 --- a/040-firestore-crud/00-starting/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]}],"date_created":"2020-06-18 21:48:34.223148","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/040-firestore-crud/00-starting/.gitignore b/040-firestore-crud/00-starting/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/040-firestore-crud/00-starting/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/040-firestore-crud/00-starting/.metadata b/040-firestore-crud/00-starting/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/040-firestore-crud/00-starting/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/040-firestore-crud/00-starting/README.md b/040-firestore-crud/00-starting/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/040-firestore-crud/00-starting/assets/fonts/OpenSans-Bold.ttf b/040-firestore-crud/00-starting/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/040-firestore-crud/00-starting/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/040-firestore-crud/00-starting/assets/fonts/OpenSans-ExtraBold.ttf b/040-firestore-crud/00-starting/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/040-firestore-crud/00-starting/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/040-firestore-crud/00-starting/assets/fonts/OpenSans-Light.ttf b/040-firestore-crud/00-starting/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/040-firestore-crud/00-starting/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/040-firestore-crud/00-starting/assets/fonts/OpenSans-Regular.ttf b/040-firestore-crud/00-starting/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/040-firestore-crud/00-starting/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/040-firestore-crud/00-starting/assets/images/icon_large.png b/040-firestore-crud/00-starting/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/040-firestore-crud/00-starting/assets/images/icon_large.png and /dev/null differ diff --git a/040-firestore-crud/00-starting/assets/images/title.png b/040-firestore-crud/00-starting/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/040-firestore-crud/00-starting/assets/images/title.png and /dev/null differ diff --git a/040-firestore-crud/00-starting/lib/constants/route_names.dart b/040-firestore-crud/00-starting/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/040-firestore-crud/00-starting/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/040-firestore-crud/00-starting/lib/locator.dart b/040-firestore-crud/00-starting/lib/locator.dart deleted file mode 100644 index ab8fe4a0..00000000 --- a/040-firestore-crud/00-starting/lib/locator.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); -} diff --git a/040-firestore-crud/00-starting/lib/main.dart b/040-firestore-crud/00-starting/lib/main.dart deleted file mode 100644 index 05de5b85..00000000 --- a/040-firestore-crud/00-starting/lib/main.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/managers/dialog_manager.dart b/040-firestore-crud/00-starting/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/040-firestore-crud/00-starting/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/040-firestore-crud/00-starting/lib/models/dialog_models.dart b/040-firestore-crud/00-starting/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/040-firestore-crud/00-starting/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/040-firestore-crud/00-starting/lib/models/post.dart b/040-firestore-crud/00-starting/lib/models/post.dart deleted file mode 100644 index efd46e05..00000000 --- a/040-firestore-crud/00-starting/lib/models/post.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - Post({ - @required this.userId, - @required this.title, - this.imageUrl, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - }; - } - - static Post fromMap(Map map) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/models/user.dart b/040-firestore-crud/00-starting/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/040-firestore-crud/00-starting/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/040-firestore-crud/00-starting/lib/services/authentication_service.dart b/040-firestore-crud/00-starting/lib/services/authentication_service.dart deleted file mode 100644 index d4edeb14..00000000 --- a/040-firestore-crud/00-starting/lib/services/authentication_service.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - } - } -} diff --git a/040-firestore-crud/00-starting/lib/services/dialog_service.dart b/040-firestore-crud/00-starting/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/040-firestore-crud/00-starting/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/040-firestore-crud/00-starting/lib/services/firestore_service.dart b/040-firestore-crud/00-starting/lib/services/firestore_service.dart deleted file mode 100644 index c3ac246c..00000000 --- a/040-firestore-crud/00-starting/lib/services/firestore_service.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } -} diff --git a/040-firestore-crud/00-starting/lib/services/navigation_service.dart b/040-firestore-crud/00-starting/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/040-firestore-crud/00-starting/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/router.dart b/040-firestore-crud/00-starting/lib/ui/router.dart deleted file mode 100644 index fd5a8550..00000000 --- a/040-firestore-crud/00-starting/lib/ui/router.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView(), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/040-firestore-crud/00-starting/lib/ui/shared/app_colors.dart b/040-firestore-crud/00-starting/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/040-firestore-crud/00-starting/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/040-firestore-crud/00-starting/lib/ui/shared/shared_styles.dart b/040-firestore-crud/00-starting/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/040-firestore-crud/00-starting/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/040-firestore-crud/00-starting/lib/ui/shared/ui_helpers.dart b/040-firestore-crud/00-starting/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/040-firestore-crud/00-starting/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/040-firestore-crud/00-starting/lib/ui/views/create_post_view.dart b/040-firestore-crud/00-starting/lib/ui/views/create_post_view.dart deleted file mode 100644 index 89787021..00000000 --- a/040-firestore-crud/00-starting/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,63 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - - CreatePostView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - // TODO: Add Post - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - child: Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ), - ) - ], - ), - )), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/views/home_view.dart b/040-firestore-crud/00-starting/lib/ui/views/home_view.dart deleted file mode 100644 index c1f1c830..00000000 --- a/040-firestore-crud/00-starting/lib/ui/views/home_view.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: - !model.busy ? Icon(Icons.add) : CircularProgressIndicator(), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: ListView.builder( - itemCount: 3, - itemBuilder: (context, index) => PostItem( - post: Post(title: '$index Title'), - ), - )) - ], - ), - ), - )); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/views/login_view.dart b/040-firestore-crud/00-starting/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/040-firestore-crud/00-starting/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/views/signup_view.dart b/040-firestore-crud/00-starting/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/040-firestore-crud/00-starting/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/views/startup_view.dart b/040-firestore-crud/00-starting/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/040-firestore-crud/00-starting/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/widgets/busy_button.dart b/040-firestore-crud/00-starting/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/040-firestore-crud/00-starting/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/widgets/busy_overlay.dart b/040-firestore-crud/00-starting/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/040-firestore-crud/00-starting/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/widgets/expansion_list.dart b/040-firestore-crud/00-starting/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/040-firestore-crud/00-starting/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/widgets/input_field.dart b/040-firestore-crud/00-starting/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/040-firestore-crud/00-starting/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/widgets/note_text.dart b/040-firestore-crud/00-starting/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/040-firestore-crud/00-starting/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/widgets/post_item.dart b/040-firestore-crud/00-starting/lib/ui/widgets/post_item.dart deleted file mode 100644 index 41c28023..00000000 --- a/040-firestore-crud/00-starting/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,35 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - const PostItem({Key key, this.post}) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Text(post.title), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () {}, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/ui/widgets/text_link.dart b/040-firestore-crud/00-starting/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/040-firestore-crud/00-starting/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/040-firestore-crud/00-starting/lib/viewmodels/base_model.dart b/040-firestore-crud/00-starting/lib/viewmodels/base_model.dart deleted file mode 100644 index de51e4c0..00000000 --- a/040-firestore-crud/00-starting/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/040-firestore-crud/00-starting/lib/viewmodels/create_post_view_model.dart b/040-firestore-crud/00-starting/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index 7d592643..00000000 --- a/040-firestore-crud/00-starting/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'package:compound/viewmodels/base_model.dart'; - -class CreatePostViewModel extends BaseModel {} diff --git a/040-firestore-crud/00-starting/lib/viewmodels/home_view_model.dart b/040-firestore-crud/00-starting/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 16aac65a..00000000 --- a/040-firestore-crud/00-starting/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - - void navigateToCreateView() => - _navigationService.navigateTo(CreatePostViewRoute); -} diff --git a/040-firestore-crud/00-starting/lib/viewmodels/login_view_model.dart b/040-firestore-crud/00-starting/lib/viewmodels/login_view_model.dart deleted file mode 100644 index c3473a10..00000000 --- a/040-firestore-crud/00-starting/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/040-firestore-crud/00-starting/lib/viewmodels/signup_view_model.dart b/040-firestore-crud/00-starting/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 25952a7f..00000000 --- a/040-firestore-crud/00-starting/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/040-firestore-crud/00-starting/lib/viewmodels/startup_view_model.dart b/040-firestore-crud/00-starting/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 45d3e880..00000000 --- a/040-firestore-crud/00-starting/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - - Future handleStartUpLogic() async { - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/040-firestore-crud/00-starting/pubspec.lock b/040-firestore-crud/00-starting/pubspec.lock deleted file mode 100644 index 98cbfe83..00000000 --- a/040-firestore-crud/00-starting/pubspec.lock +++ /dev/null @@ -1,320 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.6" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - firebase: - dependency: transitive - description: - name: firebase - url: "https://pub.dartlang.org" - source: hosted - version: "7.2.0" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/040-firestore-crud/00-starting/pubspec.yaml b/040-firestore-crud/00-starting/pubspec.yaml deleted file mode 100644 index 4931eb8c..00000000 --- a/040-firestore-crud/00-starting/pubspec.yaml +++ /dev/null @@ -1,83 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ^0.16.1 - cloud_firestore: ^0.13.6 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/040-firestore-crud/01-final/.flutter-plugins-dependencies b/040-firestore-crud/01-final/.flutter-plugins-dependencies deleted file mode 100644 index 508e2b5f..00000000 --- a/040-firestore-crud/01-final/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]}],"date_created":"2020-06-18 21:48:32.439409","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/040-firestore-crud/01-final/.gitignore b/040-firestore-crud/01-final/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/040-firestore-crud/01-final/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/040-firestore-crud/01-final/.metadata b/040-firestore-crud/01-final/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/040-firestore-crud/01-final/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/040-firestore-crud/01-final/README.md b/040-firestore-crud/01-final/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/040-firestore-crud/01-final/assets/fonts/OpenSans-Bold.ttf b/040-firestore-crud/01-final/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/040-firestore-crud/01-final/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/040-firestore-crud/01-final/assets/fonts/OpenSans-ExtraBold.ttf b/040-firestore-crud/01-final/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/040-firestore-crud/01-final/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/040-firestore-crud/01-final/assets/fonts/OpenSans-Light.ttf b/040-firestore-crud/01-final/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/040-firestore-crud/01-final/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/040-firestore-crud/01-final/assets/fonts/OpenSans-Regular.ttf b/040-firestore-crud/01-final/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/040-firestore-crud/01-final/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/040-firestore-crud/01-final/assets/images/icon_large.png b/040-firestore-crud/01-final/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/040-firestore-crud/01-final/assets/images/icon_large.png and /dev/null differ diff --git a/040-firestore-crud/01-final/assets/images/title.png b/040-firestore-crud/01-final/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/040-firestore-crud/01-final/assets/images/title.png and /dev/null differ diff --git a/040-firestore-crud/01-final/lib/constants/route_names.dart b/040-firestore-crud/01-final/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/040-firestore-crud/01-final/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/040-firestore-crud/01-final/lib/locator.dart b/040-firestore-crud/01-final/lib/locator.dart deleted file mode 100644 index ab8fe4a0..00000000 --- a/040-firestore-crud/01-final/lib/locator.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); -} diff --git a/040-firestore-crud/01-final/lib/main.dart b/040-firestore-crud/01-final/lib/main.dart deleted file mode 100644 index 05de5b85..00000000 --- a/040-firestore-crud/01-final/lib/main.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/040-firestore-crud/01-final/lib/managers/dialog_manager.dart b/040-firestore-crud/01-final/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/040-firestore-crud/01-final/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/040-firestore-crud/01-final/lib/models/dialog_models.dart b/040-firestore-crud/01-final/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/040-firestore-crud/01-final/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/040-firestore-crud/01-final/lib/models/post.dart b/040-firestore-crud/01-final/lib/models/post.dart deleted file mode 100644 index 6fab34c7..00000000 --- a/040-firestore-crud/01-final/lib/models/post.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - documentId: documentId, - ); - } -} diff --git a/040-firestore-crud/01-final/lib/models/user.dart b/040-firestore-crud/01-final/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/040-firestore-crud/01-final/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/040-firestore-crud/01-final/lib/services/authentication_service.dart b/040-firestore-crud/01-final/lib/services/authentication_service.dart deleted file mode 100644 index d4edeb14..00000000 --- a/040-firestore-crud/01-final/lib/services/authentication_service.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - } - } -} diff --git a/040-firestore-crud/01-final/lib/services/dialog_service.dart b/040-firestore-crud/01-final/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/040-firestore-crud/01-final/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/040-firestore-crud/01-final/lib/services/firestore_service.dart b/040-firestore-crud/01-final/lib/services/firestore_service.dart deleted file mode 100644 index 8704af40..00000000 --- a/040-firestore-crud/01-final/lib/services/firestore_service.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = await _postsCollectionReference.getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _postsCollectionReference.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // Add the posts onto the controller - _postsController.add(posts); - } - }); - - return _postsController.stream; - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } -} diff --git a/040-firestore-crud/01-final/lib/services/navigation_service.dart b/040-firestore-crud/01-final/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/040-firestore-crud/01-final/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/router.dart b/040-firestore-crud/01-final/lib/ui/router.dart deleted file mode 100644 index 059f9e7c..00000000 --- a/040-firestore-crud/01-final/lib/ui/router.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - var postToEdit = settings.arguments as Post; - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/040-firestore-crud/01-final/lib/ui/shared/app_colors.dart b/040-firestore-crud/01-final/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/040-firestore-crud/01-final/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/040-firestore-crud/01-final/lib/ui/shared/shared_styles.dart b/040-firestore-crud/01-final/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/040-firestore-crud/01-final/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/040-firestore-crud/01-final/lib/ui/shared/ui_helpers.dart b/040-firestore-crud/01-final/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/040-firestore-crud/01-final/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/040-firestore-crud/01-final/lib/ui/views/create_post_view.dart b/040-firestore-crud/01-final/lib/ui/views/create_post_view.dart deleted file mode 100644 index a61fef44..00000000 --- a/040-firestore-crud/01-final/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - CreatePostView({Key key, this.edittingPost}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - child: Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ), - ) - ], - ), - )), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/views/home_view.dart b/040-firestore-crud/01-final/lib/ui/views/home_view.dart deleted file mode 100644 index fcb93958..00000000 --- a/040-firestore-crud/01-final/lib/ui/views/home_view.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: - !model.busy ? Icon(Icons.add) : CircularProgressIndicator(), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => model.deletePost(index), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/views/login_view.dart b/040-firestore-crud/01-final/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/040-firestore-crud/01-final/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/views/signup_view.dart b/040-firestore-crud/01-final/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/040-firestore-crud/01-final/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/views/startup_view.dart b/040-firestore-crud/01-final/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/040-firestore-crud/01-final/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/widgets/busy_button.dart b/040-firestore-crud/01-final/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/040-firestore-crud/01-final/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/widgets/busy_overlay.dart b/040-firestore-crud/01-final/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/040-firestore-crud/01-final/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/widgets/expansion_list.dart b/040-firestore-crud/01-final/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/040-firestore-crud/01-final/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/widgets/input_field.dart b/040-firestore-crud/01-final/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/040-firestore-crud/01-final/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/widgets/note_text.dart b/040-firestore-crud/01-final/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/040-firestore-crud/01-final/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/widgets/post_item.dart b/040-firestore-crud/01-final/lib/ui/widgets/post_item.dart deleted file mode 100644 index 0ee1401a..00000000 --- a/040-firestore-crud/01-final/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Text(post.title), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/ui/widgets/text_link.dart b/040-firestore-crud/01-final/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/040-firestore-crud/01-final/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/040-firestore-crud/01-final/lib/viewmodels/base_model.dart b/040-firestore-crud/01-final/lib/viewmodels/base_model.dart deleted file mode 100644 index ac8f755b..00000000 --- a/040-firestore-crud/01-final/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/040-firestore-crud/01-final/lib/viewmodels/create_post_view_model.dart b/040-firestore-crud/01-final/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index f1abb0af..00000000 --- a/040-firestore-crud/01-final/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future addPost({@required String title}) async { - setBusy(true); - - var result; - - if (!_editting) { - result = await _firestoreService - .addPost(Post(title: title, userId: currentUser.id)); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/040-firestore-crud/01-final/lib/viewmodels/home_view_model.dart b/040-firestore-crud/01-final/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 8a47fcec..00000000 --- a/040-firestore-crud/01-final/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - setBusy(true); - await _firestoreService.deletePost(_posts[index].documentId); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } -} diff --git a/040-firestore-crud/01-final/lib/viewmodels/login_view_model.dart b/040-firestore-crud/01-final/lib/viewmodels/login_view_model.dart deleted file mode 100644 index c3473a10..00000000 --- a/040-firestore-crud/01-final/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/040-firestore-crud/01-final/lib/viewmodels/signup_view_model.dart b/040-firestore-crud/01-final/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 25952a7f..00000000 --- a/040-firestore-crud/01-final/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/040-firestore-crud/01-final/lib/viewmodels/startup_view_model.dart b/040-firestore-crud/01-final/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 45d3e880..00000000 --- a/040-firestore-crud/01-final/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - - Future handleStartUpLogic() async { - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/040-firestore-crud/01-final/pubspec.lock b/040-firestore-crud/01-final/pubspec.lock deleted file mode 100644 index 98cbfe83..00000000 --- a/040-firestore-crud/01-final/pubspec.lock +++ /dev/null @@ -1,320 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.6" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - firebase: - dependency: transitive - description: - name: firebase - url: "https://pub.dartlang.org" - source: hosted - version: "7.2.0" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/040-firestore-crud/01-final/pubspec.yaml b/040-firestore-crud/01-final/pubspec.yaml deleted file mode 100644 index 4931eb8c..00000000 --- a/040-firestore-crud/01-final/pubspec.yaml +++ /dev/null @@ -1,83 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ^0.16.1 - cloud_firestore: ^0.13.6 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/041-firestore-security-rules-with-testing/compound/.gitignore b/041-firestore-security-rules-with-testing/compound/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/041-firestore-security-rules-with-testing/compound/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/041-firestore-security-rules-with-testing/compound/firebase/.firebaserc b/041-firestore-security-rules-with-testing/compound/firebase/.firebaserc deleted file mode 100644 index 091a9705..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/.firebaserc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "projects": { - "default": "compound-53007" - } -} diff --git a/041-firestore-security-rules-with-testing/compound/firebase/.gitignore b/041-firestore-security-rules-with-testing/compound/firebase/.gitignore deleted file mode 100644 index f6268525..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/.gitignore +++ /dev/null @@ -1,65 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -firebase-debug.log* - -# Firebase cache -.firebase/ - -# Firebase config - -# Uncomment this if you'd like others to create their own Firebase project. -# For a team working on the same Firebase project(s), it is recommended to leave -# it commented so all members can deploy to the same project(s) in .firebaserc. -# .firebaserc - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (http://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env diff --git a/041-firestore-security-rules-with-testing/compound/firebase/firebase.json b/041-firestore-security-rules-with-testing/compound/firebase/firebase.json deleted file mode 100644 index d4d918a8..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/firebase.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "firestore": { - "rules": "firestore.rules", - "indexes": "firestore.indexes.json" - } -} diff --git a/041-firestore-security-rules-with-testing/compound/firebase/firestore-test.rules b/041-firestore-security-rules-with-testing/compound/firebase/firestore-test.rules deleted file mode 100644 index 7380fe5d..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/firestore-test.rules +++ /dev/null @@ -1,11 +0,0 @@ -rules_version = '2'; -service cloud.firestore { - match /databases/{database}/documents { - - // lock down the db - match /{document=**} { - allow read: if true; - allow write: if true; - } - } -} \ No newline at end of file diff --git a/041-firestore-security-rules-with-testing/compound/firebase/firestore.indexes.json b/041-firestore-security-rules-with-testing/compound/firebase/firestore.indexes.json deleted file mode 100644 index 415027e5..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/firestore.indexes.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "indexes": [], - "fieldOverrides": [] -} diff --git a/041-firestore-security-rules-with-testing/compound/firebase/firestore.rules b/041-firestore-security-rules-with-testing/compound/firebase/firestore.rules deleted file mode 100644 index 78e5afb5..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/firestore.rules +++ /dev/null @@ -1,33 +0,0 @@ -rules_version = '2'; -service cloud.firestore { - match /databases/{database}/documents { - - // lock down the db - match /{document=**} { - allow read: if false; - allow write: if false; - } - - match /posts/{postId} { - allow update: if userOwnsPost(); - allow delete: if userOwnsPost() || userIsAdmin(); - allow create: if loggedIn(); - } - - function loggedIn() { - return request.auth.uid != null; - } - - function userIsAdmin() { - return getUserData().userRole == 'Admin'; - } - - function getUserData() { - return get(/databases/$(database)/documents/users/$(request.auth.uid)).data - } - - function userOwnsPost() { - return resource.data.userId == request.auth.uid; - } - } -} \ No newline at end of file diff --git a/041-firestore-security-rules-with-testing/compound/firebase/functions/.gitignore b/041-firestore-security-rules-with-testing/compound/firebase/functions/.gitignore deleted file mode 100644 index 40b878db..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/functions/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules/ \ No newline at end of file diff --git a/041-firestore-security-rules-with-testing/compound/firebase/functions/index.js b/041-firestore-security-rules-with-testing/compound/firebase/functions/index.js deleted file mode 100644 index 06341654..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/functions/index.js +++ /dev/null @@ -1,28 +0,0 @@ -const functions = require("firebase-functions"); - -var admin = require("firebase-admin"); -var serviceAccount = require("./compound-53007-firebase-adminsdk-v3wqo-36e95e9b2e.json"); - -admin.initializeApp({ - credential: admin.credential.cert(serviceAccount) -}); - -var database = admin.firestore(); - -// // Create and Deploy Your First Cloud Functions -// // https://firebase.google.com/docs/functions/write-firebase-functions -// -exports.helloWorld = functions.https.onRequest((request, response) => { - const postsRef = database.collection("posts"); - - for (let index = 0; index < 100; index++) { - var postListRef = postsRef.doc(`post-${index}`); - postListRef.set({ - title: `Post User ${index}`, - imageUrl: "https://picsum.photos/300/300", - userId: "my-id" - }); - } - - response.send("Hello from Firebase!"); -}); diff --git a/041-firestore-security-rules-with-testing/compound/firebase/functions/package-lock.json b/041-firestore-security-rules-with-testing/compound/firebase/functions/package-lock.json deleted file mode 100644 index 202f6876..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/functions/package-lock.json +++ /dev/null @@ -1,2062 +0,0 @@ -{ - "name": "functions", - "requires": true, - "lockfileVersion": 1, - "dependencies": { - "@firebase/app-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.5.2.tgz", - "integrity": "sha512-k3zRi9gXyWrymu8OL6DA1Pz7eo+sKVBopX5ouOjQwozAZ55WhelifPC99WHmLWo8sAokNM0XDyzM7loOA5yliQ==" - }, - "@firebase/auth-interop-types": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.3.tgz", - "integrity": "sha512-Fd0MJ8hHw/MasNTJz7vl5jnMMs71X6pY/VqN0V6lqdP5HKTuyPVnffJ1d2Vb6uCLZ1D7nXAer4YWj9cOrNLPAQ==" - }, - "@firebase/component": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.6.tgz", - "integrity": "sha512-dm5pVhm+sU8ag1M3hY6vleA/H7Ed8sKRxbm4TAKhtjGHDejPXxnK0meTNydJ3MwisHWlwzGuzIEhb223K7FFxA==", - "requires": { - "@firebase/util": "0.2.41", - "tslib": "1.10.0" - } - }, - "@firebase/database": { - "version": "0.5.22", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.22.tgz", - "integrity": "sha512-3CVsmLFscFIAFOjjVhlT6HzFOhS0TKVbjhixp64oVZMOshp9qPHtHIytf6QXRAypbtZMPFAMGnhNu0pmPW/vtg==", - "requires": { - "@firebase/auth-interop-types": "0.1.3", - "@firebase/component": "0.1.6", - "@firebase/database-types": "0.4.12", - "@firebase/logger": "0.1.36", - "@firebase/util": "0.2.41", - "faye-websocket": "0.11.3", - "tslib": "1.10.0" - } - }, - "@firebase/database-types": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.4.12.tgz", - "integrity": "sha512-PVCTQRG9fnN1cam3Qr91+WzsCf9tO+lmUcPEb0uvafSFVhvx2U9OZOlYDdM5hS0MMHTNXI7Ywmc33EheIlLmMw==", - "requires": { - "@firebase/app-types": "0.5.2" - } - }, - "@firebase/logger": { - "version": "0.1.36", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.36.tgz", - "integrity": "sha512-5Z0ryTtzRk7kjUb0/18r10oXYu8mSPAjgdbLowRBP6HdSJB7BDiUIRS7iATSmUBZLTArdroSiFJ29m7YDfm/cw==" - }, - "@firebase/util": { - "version": "0.2.41", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.41.tgz", - "integrity": "sha512-QRu3wjU5I0ZBWrf4wgrEBYu5K5tkHjETMDPMY8WYCeekKB13k2MuJzHBjQVuStEOU7j6ygTAA0B8vXI/6B5D0g==", - "requires": { - "tslib": "1.10.0" - } - }, - "@google-cloud/common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.4.0.tgz", - "integrity": "sha512-zWFjBS35eI9leAHhjfeOYlK5Plcuj/77EzstnrJIZbKgF/nkqjcQuGiMCpzCwOfPyUbz8ZaEOYgbHa759AKbjg==", - "optional": true, - "requires": { - "@google-cloud/projectify": "^1.0.0", - "@google-cloud/promisify": "^1.0.0", - "arrify": "^2.0.0", - "duplexify": "^3.6.0", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^5.5.0", - "retry-request": "^4.0.0", - "teeny-request": "^6.0.0" - } - }, - "@google-cloud/firestore": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-3.6.0.tgz", - "integrity": "sha512-mAT3aEkKNsSGLApZZIUw3XMW5RUf+Y1MsoD7T5M72fDlGnAvIUHXA93wGVHpI+UPxu3XTntJ0BDSJwjlOaWM3w==", - "optional": true, - "requires": { - "deep-equal": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^1.13.0", - "readable-stream": "^3.4.0", - "through2": "^3.0.0" - } - }, - "@google-cloud/paginator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-2.0.3.tgz", - "integrity": "sha512-kp/pkb2p/p0d8/SKUu4mOq8+HGwF8NPzHWkj+VKrIPQPyMRw8deZtrO/OcSiy9C/7bpfU5Txah5ltUNfPkgEXg==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - } - }, - "@google-cloud/projectify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-1.0.4.tgz", - "integrity": "sha512-ZdzQUN02eRsmTKfBj9FDL0KNDIFNjBn/d6tHQmA/+FImH5DO6ZV8E7FzxMgAUiVAUq41RFAkb25p1oHOZ8psfg==", - "optional": true - }, - "@google-cloud/promisify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-1.0.4.tgz", - "integrity": "sha512-VccZDcOql77obTnFh0TbNED/6ZbbmHDf8UMNnzO1d5g9V0Htfm4k5cllY8P1tJsRKC3zWYGRLaViiupcgVjBoQ==", - "optional": true - }, - "@google-cloud/storage": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-4.5.0.tgz", - "integrity": "sha512-ZLFcR6CiP1AnYBA9eTtASF9Dy3wjYmGx+HZiy/LsIPN41wyBTn9yAjIOxRHiteqzX3uQzZ+VJNCB/DmTU33CeQ==", - "optional": true, - "requires": { - "@google-cloud/common": "^2.1.1", - "@google-cloud/paginator": "^2.0.0", - "@google-cloud/promisify": "^1.0.0", - "arrify": "^2.0.0", - "compressible": "^2.0.12", - "concat-stream": "^2.0.0", - "date-and-time": "^0.12.0", - "duplexify": "^3.5.0", - "extend": "^3.0.2", - "gaxios": "^2.0.1", - "gcs-resumable-upload": "^2.2.4", - "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", - "mime-types": "^2.0.8", - "onetime": "^5.1.0", - "p-limit": "^2.2.0", - "pumpify": "^2.0.0", - "readable-stream": "^3.4.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "through2": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "@grpc/grpc-js": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-0.6.18.tgz", - "integrity": "sha512-uAzv/tM8qpbf1vpx1xPMfcUMzbfdqJtdCYAqY/LsLeQQlnTb4vApylojr+wlCyr7bZeg3AFfHvtihnNOQQt/nA==", - "optional": true, - "requires": { - "semver": "^6.2.0" - } - }, - "@grpc/proto-loader": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.3.tgz", - "integrity": "sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ==", - "optional": true, - "requires": { - "lodash.camelcase": "^4.3.0", - "protobufjs": "^6.8.6" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=", - "optional": true - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", - "optional": true - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", - "optional": true - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=", - "optional": true - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=", - "optional": true - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=", - "optional": true - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=", - "optional": true - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=", - "optional": true - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=", - "optional": true - }, - "@tootallnate/once": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz", - "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==", - "optional": true - }, - "@types/body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==", - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/connect": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.33.tgz", - "integrity": "sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A==", - "requires": { - "@types/node": "*" - } - }, - "@types/express": { - "version": "4.17.3", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.3.tgz", - "integrity": "sha512-I8cGRJj3pyOLs/HndoP+25vOqhqWkAZsWMEmq1qXy/b/M3ppufecUwaK2/TVDVxcV61/iSdhykUjQQ2DLSrTdg==", - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz", - "integrity": "sha512-El9yMpctM6tORDAiBwZVLMcxoTMcqqRO9dVyYcn7ycLWbvR8klrDn8CAOwRfZujZtWD7yS/mshTdz43jMOejbg==", - "requires": { - "@types/node": "*", - "@types/range-parser": "*" - } - }, - "@types/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "@types/lodash": { - "version": "4.14.149", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz", - "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==", - "dev": true - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "optional": true - }, - "@types/mime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.1.tgz", - "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" - }, - "@types/node": { - "version": "8.10.59", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz", - "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==" - }, - "@types/range-parser": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.3.tgz", - "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==" - }, - "@types/serve-static": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.3.tgz", - "integrity": "sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g==", - "requires": { - "@types/express-serve-static-core": "*", - "@types/mime": "*" - } - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "optional": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "agent-base": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", - "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", - "optional": true, - "requires": { - "debug": "4" - } - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "optional": true - }, - "bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "optional": true - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "optional": true - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "optional": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "optional": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "optional": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "optional": true - }, - "cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "optional": true - }, - "date-and-time": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-0.12.0.tgz", - "integrity": "sha512-n2RJIAp93AucgF/U/Rz5WRS2Hjg5Z+QxscaaMCi6pVZT1JpJKRH+C08vyH/lRR1kxNXnPxgo3lWfd+jCb/UcuQ==", - "optional": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.1.tgz", - "integrity": "sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==", - "optional": true, - "requires": { - "es-abstract": "^1.16.3", - "es-get-iterator": "^1.0.1", - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "isarray": "^2.0.5", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0", - "side-channel": "^1.0.1", - "which-boxed-primitive": "^1.0.1", - "which-collection": "^1.0.0" - } - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "optional": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", - "requires": { - "streamsearch": "0.1.2" - } - }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "optional": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "optional": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - } - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "optional": true, - "requires": { - "once": "^1.4.0" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "optional": true - }, - "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", - "optional": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "optional": true, - "requires": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "optional": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "optional": true - }, - "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", - "requires": { - "bytes": "3.1.2", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - } - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - } - }, - "qs": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", - "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", - "requires": { - "side-channel": "^1.0.4" - } - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "dependencies": { - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "optional": true - }, - "fast-text-encoding": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.1.tgz", - "integrity": "sha512-x4FEgaz3zNRtJfLFqJmHWxkMDDvXVtaznj2V9jiP8ACUJrUgist4bP9FmDL2Vew2Y9mEQI/tG4GqabaitYp9CQ==", - "optional": true - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "firebase-admin": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-8.9.2.tgz", - "integrity": "sha512-ix4qcx+hHnr3mnc41Z8EzQa9Mr+2nhogLEv6ktkOCCpdKJ+9HxW9vikRCElSbC8ICHLD0KIH0GVOIZK80vbvqw==", - "requires": { - "@firebase/database": "^0.5.17", - "@google-cloud/firestore": "^3.0.0", - "@google-cloud/storage": "^4.1.2", - "@types/node": "^8.10.59", - "dicer": "^0.3.0", - "jsonwebtoken": "8.1.0", - "node-forge": "0.7.4" - } - }, - "firebase-functions": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/firebase-functions/-/firebase-functions-3.3.0.tgz", - "integrity": "sha512-dP6PCG+OwR6RtFpOqwPsLnfiCr3CwXAm/SVGMbO53vDAk0nhUQ1WGAyHDYmIyMAkaLJkIKGwDnX7XmZ5+yAg7g==", - "requires": { - "@types/express": "^4.17.0", - "cors": "^2.8.5", - "express": "^4.17.1", - "jsonwebtoken": "^8.5.1", - "lodash": "^4.17.14" - }, - "dependencies": { - "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", - "requires": { - "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.1.1", - "semver": "^5.6.0" - } - }, - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "firebase-functions-test": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/firebase-functions-test/-/firebase-functions-test-0.1.7.tgz", - "integrity": "sha512-/zVQhaUZ+M7z25aUaZSIah0MIDZIfnRfQxtHYTE8hgUgODmKdaMX20vh5Gv23hnCPauIHuYb7XFTUOZiWU1udA==", - "dev": true, - "requires": { - "@types/lodash": "^4.14.104", - "lodash": "^4.17.5" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "optional": true - }, - "gaxios": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.2.tgz", - "integrity": "sha512-K/+py7UvKRDaEwEKlLiRKrFr+wjGjsMz5qH7Vs549QJS7cpSCOT/BbWL7pzqECflc46FcNPipjSfB+V1m8PAhw==", - "optional": true, - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.3.0" - } - }, - "gcp-metadata": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-3.5.0.tgz", - "integrity": "sha512-ZQf+DLZ5aKcRpLzYUyBS3yo3N0JSa82lNDO8rj3nMSlovLcz2riKFBsYgDzeXcv75oo5eqB2lx+B14UvPoCRnA==", - "optional": true, - "requires": { - "gaxios": "^2.1.0", - "json-bigint": "^0.3.0" - } - }, - "gcs-resumable-upload": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-2.3.2.tgz", - "integrity": "sha512-OPS0iAmPCV+r7PziOIhyxmQOzsazFCy76yYDOS/Z80O/7cuny1KMfqDQa2T0jLaL8EreTU7EMZG5pUuqBKgzHA==", - "optional": true, - "requires": { - "abort-controller": "^3.0.0", - "configstore": "^5.0.0", - "gaxios": "^2.0.0", - "google-auth-library": "^5.0.0", - "pumpify": "^2.0.0", - "stream-events": "^1.0.4" - } - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "dependencies": { - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - } - } - }, - "google-auth-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.10.1.tgz", - "integrity": "sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^2.1.0", - "gcp-metadata": "^3.4.0", - "gtoken": "^4.1.0", - "jws": "^4.0.0", - "lru-cache": "^5.0.0" - } - }, - "google-gax": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-1.14.2.tgz", - "integrity": "sha512-Nde+FdqALbV3QgMA4KlkxOHfrj9busnZ3EECwy/1gDJm9vhKGwDLWzErqRU5g80OoGSAMgyY7DWIfqz7ina4Jw==", - "optional": true, - "requires": { - "@grpc/grpc-js": "^0.6.18", - "@grpc/proto-loader": "^0.5.1", - "@types/fs-extra": "^8.0.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^3.6.0", - "google-auth-library": "^5.0.0", - "is-stream-ended": "^0.1.4", - "lodash.at": "^4.6.0", - "lodash.has": "^4.5.2", - "node-fetch": "^2.6.0", - "protobufjs": "^6.8.8", - "retry-request": "^4.0.0", - "semver": "^6.0.0", - "walkdir": "^0.4.0" - } - }, - "google-p12-pem": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.4.tgz", - "integrity": "sha512-S4blHBQWZRnEW44OcR7TL9WR+QCqByRvhNDZ/uuQfpxywfupikf/miba8js1jZi6ZOGv5slgSuoshCWh6EMDzg==", - "optional": true, - "requires": { - "node-forge": "^0.9.0" - }, - "dependencies": { - "node-forge": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", - "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==", - "optional": true - } - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", - "optional": true - }, - "gtoken": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.1.4.tgz", - "integrity": "sha512-VxirzD0SWoFUo5p8RDP8Jt2AGyOmyYcT/pOUgDKJCK+iSw0TMqwrVfY37RXTNmoKwrzmDHSk0GMT9FsgVmnVSA==", - "optional": true, - "requires": { - "gaxios": "^2.1.0", - "google-p12-pem": "^2.0.0", - "jws": "^4.0.0", - "mime": "^2.2.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "optional": true - }, - "hash-stream-validation": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.2.tgz", - "integrity": "sha512-cMlva5CxWZOrlS/cY0C+9qAzesn5srhFA8IT1VPiHc9bWWBLkJfEUIZr7MWoi89oOOGmpg8ymchaOjiArsGu5A==", - "optional": true, - "requires": { - "through2": "^2.0.0" - }, - "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "optional": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "optional": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "optional": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "optional": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "optional": true - }, - "is-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.0.tgz", - "integrity": "sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==", - "optional": true - }, - "is-boolean-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.1.tgz", - "integrity": "sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==", - "optional": true - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", - "optional": true - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", - "optional": true - }, - "is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", - "optional": true - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "optional": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "optional": true - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "optional": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", - "optional": true - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "optional": true - }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "optional": true - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "optional": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "optional": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "optional": true - }, - "is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "optional": true - }, - "is-weakset": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.1.tgz", - "integrity": "sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==", - "optional": true - }, - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "optional": true - }, - "json-bigint": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", - "optional": true, - "requires": { - "bignumber.js": "^7.0.0" - } - }, - "jsonwebtoken": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz", - "integrity": "sha1-xjl80uX9WD1lwAeoPce7eOaYK4M=", - "requires": { - "jws": "^3.1.4", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.at": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=", - "optional": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "optional": true - }, - "lodash.has": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=", - "optional": true - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==", - "optional": true - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "optional": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", - "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", - "optional": true, - "requires": { - "semver": "^6.0.0" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" - }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "optional": true - }, - "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" - }, - "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", - "requires": { - "mime-db": "1.43.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "optional": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "optional": true, - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "node-forge": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.4.tgz", - "integrity": "sha512-8Df0906+tq/omxuCZD6PqhPaQDYuyJ1d+VITgxoIA8zvQd1ru+nMJcDChHH324MWitIgbVkAkQoGEEVJNpn/PA==" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", - "optional": true - }, - "object-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", - "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", - "optional": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "optional": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "optional": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "optional": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "optional": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "optional": true - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "optional": true - }, - "protobufjs": { - "version": "6.8.8", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", - "optional": true, - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "10.17.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.17.tgz", - "integrity": "sha512-gpNnRnZP3VWzzj5k3qrpRC6Rk3H/uclhAVo1aIvwzK5p5cOrs9yEyQ8H/HBsBY0u5rrWxXEiVPQ0dEB6pkjE8Q==", - "optional": true - } - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "optional": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "optional": true, - "requires": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "optional": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - } - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "optional": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "retry-request": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz", - "integrity": "sha512-BINDzVtLI2BDukjWmjAIRZ0oglnCAkpP2vQjM3jdLhmT62h0xnQgciPwBRDAvHqpkPT2Wo1XuUyLyn6nbGrZQQ==", - "optional": true, - "requires": { - "debug": "^4.1.1", - "through2": "^3.0.1" - } - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true - }, - "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", - "optional": true, - "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" - } - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "optional": true - }, - "snakeize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", - "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", - "optional": true - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "optional": true, - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "optional": true - }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" - }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", - "optional": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", - "optional": true, - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - } - } - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "optional": true - }, - "teeny-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.3.tgz", - "integrity": "sha512-TZG/dfd2r6yeji19es1cUIwAlVD8y+/svB1kAC2Y0bjEyysrfbO8EZvJBRwIE6WkwmUoB7uvWLwTIhJbMXZ1Dw==", - "optional": true, - "requires": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.2.0", - "stream-events": "^1.0.5", - "uuid": "^7.0.0" - } - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "optional": true, - "requires": { - "readable-stream": "2 || 3" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "optional": true - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "optional": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "optional": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "optional": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "optional": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" - }, - "uuid": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", - "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==", - "optional": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" - }, - "walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", - "optional": true - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "optional": true - }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "optional": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz", - "integrity": "sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==", - "optional": true, - "requires": { - "is-bigint": "^1.0.0", - "is-boolean-object": "^1.0.0", - "is-number-object": "^1.0.3", - "is-string": "^1.0.4", - "is-symbol": "^1.0.2" - } - }, - "which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "optional": true, - "requires": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "optional": true - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "optional": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "optional": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - } - } -} diff --git a/041-firestore-security-rules-with-testing/compound/firebase/functions/package.json b/041-firestore-security-rules-with-testing/compound/firebase/functions/package.json deleted file mode 100644 index c6c047c2..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/functions/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "functions", - "description": "Cloud Functions for Firebase", - "scripts": { - "serve": "firebase serve --only functions", - "shell": "firebase functions:shell", - "start": "npm run shell", - "deploy": "firebase deploy --only functions", - "logs": "firebase functions:log" - }, - "engines": { - "node": "8" - }, - "dependencies": { - "firebase-admin": "^8.9.2", - "firebase-functions": "^3.1.0" - }, - "devDependencies": { - "firebase-functions-test": "^0.1.6" - }, - "private": true -} diff --git a/041-firestore-security-rules-with-testing/compound/firebase/package-lock.json b/041-firestore-security-rules-with-testing/compound/firebase/package-lock.json deleted file mode 100644 index 16e36cd0..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/package-lock.json +++ /dev/null @@ -1,6184 +0,0 @@ -{ - "name": "firebase", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@babel/code-frame": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", - "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", - "requires": { - "@babel/highlight": "^7.8.3" - } - }, - "@babel/core": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz", - "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helpers": "^7.8.4", - "@babel/parser": "^7.8.4", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", - "lodash": "^4.17.13", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/generator": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz", - "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==", - "requires": { - "@babel/types": "^7.8.3", - "jsesc": "^2.5.1", - "lodash": "^4.17.13", - "source-map": "^0.5.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "@babel/helper-function-name": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", - "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", - "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-get-function-arity": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", - "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", - "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==" - }, - "@babel/helper-split-export-declaration": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", - "requires": { - "@babel/types": "^7.8.3" - } - }, - "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", - "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" - } - }, - "@babel/highlight": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", - "requires": { - "chalk": "^2.0.0", - "esutils": "^2.0.2", - "js-tokens": "^4.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz", - "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==" - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" - } - }, - "@babel/traverse": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.4.tgz", - "integrity": "sha512-NGLJPZwnVEyBPLI+bl9y9aSnxMhsKz42so7ApAv9D+b4vAFPpY013FTS9LdKxcABoIYFU52HcYga1pPlx454mg==", - "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.4", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.4", - "@babel/types": "^7.8.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - } - }, - "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" - }, - "@cnakazawa/watch": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.3.tgz", - "integrity": "sha512-r5160ogAvGyHsal38Kux7YYtodEKOj89RGb28ht1jh3SJb08VwRwAKKJL0bGb04Zd/3r9FL3BFIc3bBidYffCA==", - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "@firebase/analytics": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.2.12.tgz", - "integrity": "sha512-y/WwSNUOPJnAdYOxD+NCMwVbhfP/yrQrnGTn1zAAM1R8bBBmWay8HpHki7g5N3qQ+AQ+uMF6tKbp/JnJkini7A==", - "requires": { - "@firebase/analytics-types": "0.2.5", - "@firebase/component": "0.1.4", - "@firebase/installations": "0.4.1", - "@firebase/util": "0.2.39", - "tslib": "1.10.0" - } - }, - "@firebase/analytics-types": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.2.5.tgz", - "integrity": "sha512-aa746gTiILMn9TPBJXaYhYqnCL4CQwd4aYTAZseI9RZ/hf117xJTNy9/ZTmG5gl2AqxV0LgtdHYqKAjRlNqPIQ==" - }, - "@firebase/app": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.5.3.tgz", - "integrity": "sha512-cQn8eQSJRMpyIRfBi2roIiw0weAorpdJ2Ssn7yDlkMo0ZSE56MgMSlX1mcDupXgNZtG+k3E+IEr+FfzD9SQBGg==", - "requires": { - "@firebase/app-types": "0.5.0", - "@firebase/component": "0.1.4", - "@firebase/logger": "0.1.34", - "@firebase/util": "0.2.39", - "dom-storage": "2.1.0", - "tslib": "1.10.0", - "xmlhttprequest": "1.8.0" - } - }, - "@firebase/app-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.5.0.tgz", - "integrity": "sha512-8j+vCXTpAkYGcFk86mPZ90V6HMFmn196RIEW9Opi0PN+VrPFC1l/eW0gptM8v7VXaQhECOxws3TN2g+dDaeSYA==" - }, - "@firebase/auth": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.13.4.tgz", - "integrity": "sha512-dFDuLMHHmigs9ZH56h+UO78SMuvYkwRcPbEudaemYisGLXnYFa0pUKS2WfvA/9d/14X/VnzG8NGApAw5BylpvA==", - "requires": { - "@firebase/auth-types": "0.9.4" - } - }, - "@firebase/auth-interop-types": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.1.tgz", - "integrity": "sha512-rNpCOyCspZvNDoQVQLQQgWAGBMB2ClCWKN1c8cEFgLNFgnMJrjVB+tcL7KW2q2UjKa7l8Mxgwys7szTiEDAcvA==" - }, - "@firebase/auth-types": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.9.4.tgz", - "integrity": "sha512-06ZrpYz1GaUfIJs7C3Yf4lARH8+2kzgKfgG/9B3FaGHFYLa5U7rLBGGaca4oiVI12jmhe9CV3+M8e3U2CRCr2w==" - }, - "@firebase/component": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.4.tgz", - "integrity": "sha512-k3JZFUyHnSWC/7v+x+pIHLDNJPYA6xd7nqrQASOXH5TXhCR9meg0VsnJb+knD18491iRMKJnQWNSHdqPK9AX5w==", - "requires": { - "@firebase/util": "0.2.39", - "tslib": "1.10.0" - } - }, - "@firebase/database": { - "version": "0.5.20", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.5.20.tgz", - "integrity": "sha512-31dNLqMW4nGrGzIDS5hh+1LFzkr/m1Kb+EcftQGC3NaGC3zHwGyG7ijn+Xo7gIWtXukvJvm1cFC7R+eOCPEejw==", - "requires": { - "@firebase/auth-interop-types": "0.1.1", - "@firebase/component": "0.1.4", - "@firebase/database-types": "0.4.10", - "@firebase/logger": "0.1.34", - "@firebase/util": "0.2.39", - "faye-websocket": "0.11.3", - "tslib": "1.10.0" - } - }, - "@firebase/database-types": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.4.10.tgz", - "integrity": "sha512-66puLsckt5HASgRN3CfhLn2iuGrgCjfH3u17OL0f5MtEweYLx+yW2QW5d539Wx30xD4B+INEdaRetw6xEa9t7g==", - "requires": { - "@firebase/app-types": "0.5.0" - } - }, - "@firebase/firestore": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.10.0.tgz", - "integrity": "sha512-m7RjiEmACg7BHZdAgWKEE5NGbXrc56cQeVqh1ptRNTjPZG0W0Ygtp4hmU5k9FuN9JogIZqBqcXRmRQcq9qOkNw==", - "requires": { - "@firebase/component": "0.1.4", - "@firebase/firestore-types": "1.9.0", - "@firebase/logger": "0.1.34", - "@firebase/util": "0.2.39", - "@firebase/webchannel-wrapper": "0.2.35", - "@grpc/proto-loader": "^0.5.0", - "grpc": "1.24.2", - "tslib": "1.10.0" - } - }, - "@firebase/firestore-types": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-1.9.0.tgz", - "integrity": "sha512-UOtneGMUTLr58P56Y0GT/c4ZyC39vOoRAzgwad4PIsyc7HlKShbHKJpyys/LdlUYIsQdy/2El3Qy1veiBQ+ZJg==" - }, - "@firebase/functions": { - "version": "0.4.31", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.4.31.tgz", - "integrity": "sha512-6AiAoABRaFb0M0MMIHDXfbvNVduKNdLAGG+6FtMNuUzFbWiLLKsPgFy0jMkF874z7eIDT4XhZLNAasFVor/alw==", - "requires": { - "@firebase/component": "0.1.4", - "@firebase/functions-types": "0.3.13", - "@firebase/messaging-types": "0.4.1", - "isomorphic-fetch": "2.2.1", - "tslib": "1.10.0" - } - }, - "@firebase/functions-types": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.3.13.tgz", - "integrity": "sha512-wD075tCmZo+t/GHs5xMhi3irwjbc6SWnjXAIHjuNhVDKic5gQNkHH5QnxX930WPrPhD0RV9wuSP15fy9T1mvjw==" - }, - "@firebase/installations": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.4.1.tgz", - "integrity": "sha512-rZj3dce54YkKHLJpSvxtf+OWF1/yaQe3jRWt5Fy70XTTYv60RM5DkjbbjL7ItflBMzXZCVUTiBUogFWN4Y1LVg==", - "requires": { - "@firebase/component": "0.1.4", - "@firebase/installations-types": "0.3.0", - "@firebase/util": "0.2.39", - "idb": "3.0.2", - "tslib": "1.10.0" - } - }, - "@firebase/installations-types": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.3.0.tgz", - "integrity": "sha512-1W82H1F4WfuWjftMiWLNUTy1w2SD7svn8/U8k6T/CJSnzkET6m+3pPt3Q4FDI6E2zOgU8ZVGWm9IZ4DK84mP/A==" - }, - "@firebase/logger": { - "version": "0.1.34", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.1.34.tgz", - "integrity": "sha512-J2h6ylpd1IcuonRM3HBdXThitds6aQSIeoPYRPvApSFy82NhFPKRzJlflAhlQWjJOh59/jyQBGWJNxCL6fp4hw==" - }, - "@firebase/messaging": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.6.3.tgz", - "integrity": "sha512-PgkKsJwErLDsCqrcFSaLgFH/oXzMcwBbNN7HyAXTsWxUwhBbG7c5xtGRGd21F82EEmXcFl3VU/Y/kyYuXskrbQ==", - "requires": { - "@firebase/component": "0.1.4", - "@firebase/installations": "0.4.1", - "@firebase/messaging-types": "0.4.1", - "@firebase/util": "0.2.39", - "idb": "3.0.2", - "tslib": "1.10.0" - } - }, - "@firebase/messaging-types": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.4.1.tgz", - "integrity": "sha512-z2ki1nIE8TYH9LiXdozEzrPi9Cfckh9/x7HbDfj5KoVFYYvwLndUczstpKm2hvAUD3GuJF0JRUuxMHpJ6pwqzQ==" - }, - "@firebase/performance": { - "version": "0.2.31", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.2.31.tgz", - "integrity": "sha512-vg60k0wnMeTRhW8myOiJPn8vuVHlusnhg2YlN0PlH2epvzUPUv9bAeYVC6/XESORxmBmqUzfMsAaD3oCAQ8boQ==", - "requires": { - "@firebase/component": "0.1.4", - "@firebase/installations": "0.4.1", - "@firebase/logger": "0.1.34", - "@firebase/performance-types": "0.0.8", - "@firebase/util": "0.2.39", - "tslib": "1.10.0" - } - }, - "@firebase/performance-types": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.0.8.tgz", - "integrity": "sha512-3RK15Bct9PRdr0YBdbZV2KTi5yrPzscJVEsdnsLHuwXBntqlQaouQqwlCNFn25dtCMY0cgV/yiaFmuo13mbJ8A==" - }, - "@firebase/polyfill": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.31.tgz", - "integrity": "sha512-7XItMz50tdba57tCOTCSH8REvHYbrTU7MBOksnNZ3td/J9W/RkCPcLVSSnFWNmn0Jv1aufpUevryX1J4DZ/oiw==", - "requires": { - "core-js": "3.6.2", - "promise-polyfill": "8.1.3", - "whatwg-fetch": "2.0.4" - }, - "dependencies": { - "whatwg-fetch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" - } - } - }, - "@firebase/remote-config": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.1.12.tgz", - "integrity": "sha512-L8Qr2waj5NjgWYsjjhvMmSnUaav4LPdrshdz/l/QPBCkNpF5+hIxbeG2f8609D5brcQVnG7uR4lcWfkzl+zsfQ==", - "requires": { - "@firebase/component": "0.1.4", - "@firebase/installations": "0.4.1", - "@firebase/logger": "0.1.34", - "@firebase/remote-config-types": "0.1.5", - "@firebase/util": "0.2.39", - "tslib": "1.10.0" - } - }, - "@firebase/remote-config-types": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.1.5.tgz", - "integrity": "sha512-1JR0XGVN0dNKJlu5sMYh0qL0jC85xNgXfUquUGNHhy9lH3++t1gD91MeiDBgxI73oFQR7PEPeu+CTeDS0g8lWQ==" - }, - "@firebase/storage": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.3.25.tgz", - "integrity": "sha512-0dgfrbPuwFDMOsC3VeENSt4L5bTsLq/5spdDn/Cjj57T0lVRaXipmgD09y8CJ0/SYPfiRoxmMWKCMnVNeSDL/g==", - "requires": { - "@firebase/component": "0.1.4", - "@firebase/storage-types": "0.3.8", - "@firebase/util": "0.2.39", - "tslib": "1.10.0" - } - }, - "@firebase/storage-types": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.3.8.tgz", - "integrity": "sha512-F0ED2WZaGjhjEdOk85c/1ikDQdWM1NiATFuTmRsaGYZyoERiwh/Mr6FnjqnLIeiJZqa6v2hk/aUgKosXjMWH/Q==" - }, - "@firebase/testing": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@firebase/testing/-/testing-0.16.7.tgz", - "integrity": "sha512-qH1TgQ3FQExmnFh6Ny0Kt8VKYBoE/KmtCs3HGhVjM9xJMrOconufZPM6amwVnvRQIKrMUCNgy2c9XGBHQ3ZXvQ==", - "requires": { - "@firebase/logger": "0.1.34", - "@firebase/util": "0.2.39", - "@types/request": "2.48.4", - "firebase": "7.8.0", - "grpc": "1.24.2", - "request": "2.88.0" - } - }, - "@firebase/util": { - "version": "0.2.39", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.2.39.tgz", - "integrity": "sha512-hxbQJ9TkFzd6g8/ZcWBjdrxjxS0jYnR1EN3i1ah7i3KtvuxAtwNJ04YRf0QhKhCoitTkJ1Yn3cGb0kFnGtJVRA==", - "requires": { - "tslib": "1.10.0" - } - }, - "@firebase/webchannel-wrapper": { - "version": "0.2.35", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.35.tgz", - "integrity": "sha512-7njiGBbFW0HCnuKNEJLcQt9EjfOzG8EJiXlFJwA3XfgiFxPVHmXrcF4d5yold2wfiwCwrXpeNTGZ854oRr6Hcw==" - }, - "@google-cloud/common": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-2.4.0.tgz", - "integrity": "sha512-zWFjBS35eI9leAHhjfeOYlK5Plcuj/77EzstnrJIZbKgF/nkqjcQuGiMCpzCwOfPyUbz8ZaEOYgbHa759AKbjg==", - "optional": true, - "requires": { - "@google-cloud/projectify": "^1.0.0", - "@google-cloud/promisify": "^1.0.0", - "arrify": "^2.0.0", - "duplexify": "^3.6.0", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^5.5.0", - "retry-request": "^4.0.0", - "teeny-request": "^6.0.0" - } - }, - "@google-cloud/firestore": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-3.6.0.tgz", - "integrity": "sha512-mAT3aEkKNsSGLApZZIUw3XMW5RUf+Y1MsoD7T5M72fDlGnAvIUHXA93wGVHpI+UPxu3XTntJ0BDSJwjlOaWM3w==", - "optional": true, - "requires": { - "deep-equal": "^2.0.0", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^1.13.0", - "readable-stream": "^3.4.0", - "through2": "^3.0.0" - } - }, - "@google-cloud/paginator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-2.0.3.tgz", - "integrity": "sha512-kp/pkb2p/p0d8/SKUu4mOq8+HGwF8NPzHWkj+VKrIPQPyMRw8deZtrO/OcSiy9C/7bpfU5Txah5ltUNfPkgEXg==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - } - }, - "@google-cloud/projectify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-1.0.4.tgz", - "integrity": "sha512-ZdzQUN02eRsmTKfBj9FDL0KNDIFNjBn/d6tHQmA/+FImH5DO6ZV8E7FzxMgAUiVAUq41RFAkb25p1oHOZ8psfg==", - "optional": true - }, - "@google-cloud/promisify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-1.0.4.tgz", - "integrity": "sha512-VccZDcOql77obTnFh0TbNED/6ZbbmHDf8UMNnzO1d5g9V0Htfm4k5cllY8P1tJsRKC3zWYGRLaViiupcgVjBoQ==", - "optional": true - }, - "@google-cloud/storage": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-4.5.0.tgz", - "integrity": "sha512-ZLFcR6CiP1AnYBA9eTtASF9Dy3wjYmGx+HZiy/LsIPN41wyBTn9yAjIOxRHiteqzX3uQzZ+VJNCB/DmTU33CeQ==", - "optional": true, - "requires": { - "@google-cloud/common": "^2.1.1", - "@google-cloud/paginator": "^2.0.0", - "@google-cloud/promisify": "^1.0.0", - "arrify": "^2.0.0", - "compressible": "^2.0.12", - "concat-stream": "^2.0.0", - "date-and-time": "^0.12.0", - "duplexify": "^3.5.0", - "extend": "^3.0.2", - "gaxios": "^2.0.1", - "gcs-resumable-upload": "^2.2.4", - "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", - "mime-types": "^2.0.8", - "onetime": "^5.1.0", - "p-limit": "^2.2.0", - "pumpify": "^2.0.0", - "readable-stream": "^3.4.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "through2": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "@grpc/grpc-js": { - "version": "0.6.18", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-0.6.18.tgz", - "integrity": "sha512-uAzv/tM8qpbf1vpx1xPMfcUMzbfdqJtdCYAqY/LsLeQQlnTb4vApylojr+wlCyr7bZeg3AFfHvtihnNOQQt/nA==", - "optional": true, - "requires": { - "semver": "^6.2.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true - } - } - }, - "@grpc/proto-loader": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.3.tgz", - "integrity": "sha512-8qvUtGg77G2ZT2HqdqYoM/OY97gQd/0crSG34xNmZ4ZOsv3aQT/FQV9QfZPazTGna6MIoyUd+u6AxsoZjJ/VMQ==", - "requires": { - "lodash.camelcase": "^4.3.0", - "protobufjs": "^6.8.6" - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==" - }, - "@jest/console": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-25.1.0.tgz", - "integrity": "sha512-3P1DpqAMK/L07ag/Y9/Jup5iDEG9P4pRAuZiMQnU0JB3UOvCyYCjCoxr7sIA80SeyUCUKrr24fKAxVpmBgQonA==", - "requires": { - "@jest/source-map": "^25.1.0", - "chalk": "^3.0.0", - "jest-util": "^25.1.0", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-25.1.0.tgz", - "integrity": "sha512-iz05+NmwCmZRzMXvMo6KFipW7nzhbpEawrKrkkdJzgytavPse0biEnCNr2wRlyCsp3SmKaEY+SGv7YWYQnIdig==", - "requires": { - "@jest/console": "^25.1.0", - "@jest/reporters": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.3", - "jest-changed-files": "^25.1.0", - "jest-config": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-resolve-dependencies": "^25.1.0", - "jest-runner": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", - "jest-watcher": "^25.1.0", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "realpath-native": "^1.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "@jest/environment": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-25.1.0.tgz", - "integrity": "sha512-cTpUtsjU4cum53VqBDlcW0E4KbQF03Cn0jckGPW/5rrE9tb+porD3+hhLtHAwhthsqfyF+bizyodTlsRA++sHg==", - "requires": { - "@jest/fake-timers": "^25.1.0", - "@jest/types": "^25.1.0", - "jest-mock": "^25.1.0" - } - }, - "@jest/fake-timers": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-25.1.0.tgz", - "integrity": "sha512-Eu3dysBzSAO1lD7cylZd/CVKdZZ1/43SF35iYBNV1Lvvn2Undp3Grwsv8PrzvbLhqwRzDd4zxrY4gsiHc+wygQ==", - "requires": { - "@jest/types": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-util": "^25.1.0", - "lolex": "^5.0.0" - } - }, - "@jest/reporters": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-25.1.0.tgz", - "integrity": "sha512-ORLT7hq2acJQa8N+NKfs68ZtHFnJPxsGqmofxW7v7urVhzJvpKZG9M7FAcgh9Ee1ZbCteMrirHA3m5JfBtAaDg==", - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^25.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.0", - "jest-haste-map": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", - "node-notifier": "^6.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^3.1.0", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^4.0.1" - } - }, - "@jest/source-map": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-25.1.0.tgz", - "integrity": "sha512-ohf2iKT0xnLWcIUhL6U6QN+CwFWf9XnrM2a6ybL9NXxJjgYijjLSitkYHIdzkd8wFliH73qj/+epIpTiWjRtAA==", - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.3", - "source-map": "^0.6.0" - } - }, - "@jest/test-result": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-25.1.0.tgz", - "integrity": "sha512-FZzSo36h++U93vNWZ0KgvlNuZ9pnDnztvaM7P/UcTx87aPDotG18bXifkf1Ji44B7k/eIatmMzkBapnAzjkJkg==", - "requires": { - "@jest/console": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-25.1.0.tgz", - "integrity": "sha512-WgZLRgVr2b4l/7ED1J1RJQBOharxS11EFhmwDqknpknE0Pm87HLZVS2Asuuw+HQdfQvm2aXL2FvvBLxOD1D0iw==", - "requires": { - "@jest/test-result": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-runner": "^25.1.0", - "jest-runtime": "^25.1.0" - } - }, - "@jest/transform": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-25.1.0.tgz", - "integrity": "sha512-4ktrQ2TPREVeM+KxB4zskAT84SnmG1vaz4S+51aTefyqn3zocZUnliLLm5Fsl85I3p/kFPN4CRp1RElIfXGegQ==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^25.1.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^3.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-util": "^25.1.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "realpath-native": "^1.1.0", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - } - }, - "@jest/types": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.1.0.tgz", - "integrity": "sha512-VpOtt7tCrgvamWZh1reVsGADujKigBUFTi19mlRjqEGsE8qH4r3s+skY33dNdXOwyZIvuftZ5tqdF1IgsMejMA==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@sinonjs/commons": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.7.0.tgz", - "integrity": "sha512-qbk9AP+cZUsKdW1GJsBpxPKFmCJ0T8swwzVje3qFd+AkQb74Q/tiuzrdfFg8AD2g5HH/XbE/I8Uc1KYHVYWfhg==", - "requires": { - "type-detect": "4.0.8" - } - }, - "@tootallnate/once": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.0.0.tgz", - "integrity": "sha512-KYyTT/T6ALPkIRd2Ge080X/BsXvy9O0hcWTtMWkPvwAwF99+vn6Dv4GzrFT/Nn1LePr+FFDbRXXlqmsy9lw2zA==", - "optional": true - }, - "@types/babel__core": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", - "integrity": "sha512-8fBo0UR2CcwWxeX7WIIgJ7lXjasFxoYgRnFHUj+hRvKkpiBJbxhdAPTCY6/ZKM0uxANFVzt4yObSLuTiTnazDA==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@types/babel__traverse": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.8.tgz", - "integrity": "sha512-yGeB2dHEdvxjP0y4UbRtQaSkXJ9649fYCmIdRoul5kfAoGCwxuCbMhag0k3RPfnuh9kPGm8x89btcfDEXdVWGw==", - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/bytebuffer": { - "version": "5.0.40", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.40.tgz", - "integrity": "sha512-h48dyzZrPMz25K6Q4+NCwWaxwXany2FhQg/ErOcdZS1ZpsaDnDMZg8JYLMTGz7uvXKrcKGJUZJlZObyfgdaN9g==", - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, - "@types/caseless": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.2.tgz", - "integrity": "sha512-6ckxMjBBD8URvjB6J3NcnuAn5Pkl7t3TizAg+xdlzzQGSPSmBcXf8KoIH0ua/i+tio+ZRUHEXp0HEmvaR4kt0w==" - }, - "@types/color-name": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" - }, - "@types/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz", - "integrity": "sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==" - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz", - "integrity": "sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==", - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==" - }, - "@types/node": { - "version": "13.7.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz", - "integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==" - }, - "@types/request": { - "version": "2.48.4", - "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.4.tgz", - "integrity": "sha512-W1t1MTKYR8PxICH+A4HgEIPuAC3sbljoEVfyZbeFJJDbr30guDspJri2XOaM2E+Un7ZjrihaDi7cf6fPa2tbgw==", - "requires": { - "@types/caseless": "*", - "@types/node": "*", - "@types/tough-cookie": "*", - "form-data": "^2.5.0" - } - }, - "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==" - }, - "@types/tough-cookie": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.6.tgz", - "integrity": "sha512-wHNBMnkoEBiRAd3s8KTKwIuO9biFtTf0LehITzBhSco+HQI0xkXZbLOD55SW3Aqw3oUkHstkm5SPv58yaAdFPQ==" - }, - "@types/yargs": { - "version": "15.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.3.tgz", - "integrity": "sha512-XCMQRK6kfpNBixHLyHUsGmXrpEmFFxzMrcnSXFMziHd8CoNJo8l16FkHyQq4x+xbM7E2XL83/O78OD8u+iZTdQ==", - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-15.0.0.tgz", - "integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==" - }, - "abab": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", - "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==" - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "optional": true, - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", - "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==" - }, - "acorn-globals": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", - "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", - "requires": { - "acorn": "^6.0.1", - "acorn-walk": "^6.0.1" - }, - "dependencies": { - "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==" - } - } - }, - "acorn-walk": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", - "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" - }, - "agent-base": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", - "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", - "optional": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", - "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", - "requires": { - "type-fest": "^0.8.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", - "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=" - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "optional": true - }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, - "asn1": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", - "requires": { - "safer-buffer": "~2.1.0" - } - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" - }, - "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==" - }, - "aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" - }, - "aws4": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", - "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==" - }, - "babel-jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-25.1.0.tgz", - "integrity": "sha512-tz0VxUhhOE2y+g8R2oFrO/2VtVjA1lkJeavlhExuRBg3LdNJY9gwQ+Vcvqt9+cqy71MCTJhewvTB7Qtnnr9SWg==", - "requires": { - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/babel__core": "^7.1.0", - "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^25.1.0", - "chalk": "^3.0.0", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", - "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^4.0.0", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.1.0.tgz", - "integrity": "sha512-oIsopO41vW4YFZ9yNYoLQATnnN46lp+MZ6H4VvPKFkcc2/fkl3CfE/NZZSmnEIEsJRmJAgkVEK0R7Zbl50CpTw==", - "requires": { - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-25.1.0.tgz", - "integrity": "sha512-eCGn64olaqwUMaugXsTtGAM2I0QTahjEtnRu0ql8Ie+gDWAc1N6wqN0k2NilnyTunM69Pad7gJY7LOtwLimoFQ==", - "requires": { - "@babel/plugin-syntax-bigint": "^7.0.0", - "@babel/plugin-syntax-object-rest-spread": "^7.0.0", - "babel-plugin-jest-hoist": "^25.1.0" - } - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "optional": true - }, - "bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", - "requires": { - "tweetnacl": "^0.14.3" - } - }, - "bignumber.js": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==", - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-process-hrtime": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" - }, - "browser-resolve": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", - "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" - } - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" - }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "requires": { - "long": "~3" - }, - "dependencies": { - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" - }, - "capture-exit": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-2.0.0.tgz", - "integrity": "sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==", - "requires": { - "rsvp": "^4.8.4" - } - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==" - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" - }, - "collect-v8-coverage": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.0.tgz", - "integrity": "sha512-VKIhJgvk8E1W28m5avZ2Gv2Ruv5YiF56ug2oclvaG9md69BuZImMG2sk9g7QNKLUbtYAKQjXjYxbYZVUlMMKmQ==" - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "optional": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "optional": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "configstore": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", - "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", - "optional": true, - "requires": { - "dot-prop": "^5.2.0", - "graceful-fs": "^4.1.2", - "make-dir": "^3.0.0", - "unique-string": "^2.0.0", - "write-file-atomic": "^3.0.0", - "xdg-basedir": "^4.0.0" - } - }, - "convert-source-map": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", - "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - } - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" - }, - "core-js": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.6.2.tgz", - "integrity": "sha512-hIE5dXkRzRvnZ5vhkRfQxUvDxQZmD9oueA08jDYRBKJHx+VIl/Pne/e0A4x9LObEEthC/TqiZybUoNM4tRgnKg==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-random-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", - "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", - "optional": true - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==" - }, - "cssstyle": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz", - "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==", - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" - } - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "data-urls": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", - "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", - "requires": { - "abab": "^2.0.0", - "whatwg-mimetype": "^2.2.0", - "whatwg-url": "^7.0.0" - } - }, - "date-and-time": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-0.12.0.tgz", - "integrity": "sha512-n2RJIAp93AucgF/U/Rz5WRS2Hjg5Z+QxscaaMCi6pVZT1JpJKRH+C08vyH/lRR1kxNXnPxgo3lWfd+jCb/UcuQ==", - "optional": true - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" - }, - "deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.0.1.tgz", - "integrity": "sha512-7Et6r6XfNW61CPPCIYfm1YPGSmh6+CliYeL4km7GWJcpX5LTAflGF8drLLR+MZX+2P3NZfAfSduutBbSWqER4g==", - "optional": true, - "requires": { - "es-abstract": "^1.16.3", - "es-get-iterator": "^1.0.1", - "is-arguments": "^1.0.4", - "is-date-object": "^1.0.1", - "is-regex": "^1.0.4", - "isarray": "^2.0.5", - "object-is": "^1.0.1", - "object-keys": "^1.1.1", - "regexp.prototype.flags": "^1.2.0", - "side-channel": "^1.0.1", - "which-boxed-primitive": "^1.0.1", - "which-collection": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "optional": true - } - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==" - }, - "dicer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.3.0.tgz", - "integrity": "sha512-MdceRRWqltEG2dZqO769g27N/3PXfcKl04VhYnBlo2YhH7zPi88VebsjTKclaOyiuMaGU72hTfw3VkUitGcVCA==", - "requires": { - "streamsearch": "0.1.2" - } - }, - "diff-sequences": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.1.0.tgz", - "integrity": "sha512-nFIfVk5B/NStCsJ+zaPO4vYuLjlzQ6uFvPxzYyHlejNZ/UGa7G/n7peOXVrVNvRuyfstt+mZQYGpjxg9Z6N8Kw==" - }, - "dom-storage": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dom-storage/-/dom-storage-2.1.0.tgz", - "integrity": "sha512-g6RpyWXzl0RR6OTElHKBl7nwnK87GUyZMYC7JWsB/IA73vpqK2K6LT39x4VepLxlSsWBFrPVLnsSR5Jyty0+2Q==" - }, - "domexception": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", - "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", - "requires": { - "webidl-conversions": "^4.0.2" - } - }, - "dot-prop": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", - "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", - "optional": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "optional": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - } - } - }, - "ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", - "requires": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "requires": { - "iconv-lite": "~0.4.13" - } - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "requires": { - "once": "^1.4.0" - } - }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "optional": true - }, - "es-abstract": { - "version": "1.17.4", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", - "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.1.5", - "is-regex": "^1.0.5", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimleft": "^2.1.1", - "string.prototype.trimright": "^2.1.1" - } - }, - "es-get-iterator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.0.tgz", - "integrity": "sha512-UfrmHuWQlNMTs35e1ypnvikg6jCz3SK8v8ImvmDsh36fCVUR1MqoFDiyn0/k52C8NqO3YsO8Oe0azeesNuqSsQ==", - "optional": true, - "requires": { - "es-abstract": "^1.17.4", - "has-symbols": "^1.0.1", - "is-arguments": "^1.0.4", - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-string": "^1.0.5", - "isarray": "^2.0.5" - }, - "dependencies": { - "isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "optional": true - } - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escodegen": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.13.0.tgz", - "integrity": "sha512-eYk2dCkxR07DsHA/X2hRBj0CFAZeri/LyDMc0C8JT1Hqi6JnVpMhJ7XFITbb0+yZS3lVkaPL2oCkZ3AVmeVbMw==", - "requires": { - "esprima": "^4.0.1", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", - "optional": true - }, - "exec-sh": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.3.4.tgz", - "integrity": "sha512-sEFIkc61v75sWeOe72qyrqg2Qg0OuLESziUDk/O/z2qgS15y2gWVFrI6f2Qn/qw/0/NCfCEsmNA4zOjkwEZT1A==" - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - } - } - }, - "expect": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-25.1.0.tgz", - "integrity": "sha512-wqHzuoapQkhc3OKPlrpetsfueuEiMf3iWh0R8+duCu9PIjXoP7HgD5aeypwTnXUAjC8aMsiVDaWwlbJ1RlQ38g==", - "requires": { - "@jest/types": "^25.1.0", - "ansi-styles": "^4.0.0", - "jest-get-type": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-regex-util": "^25.1.0" - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" - }, - "fast-deep-equal": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", - "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==" - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" - }, - "fast-text-encoding": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.1.tgz", - "integrity": "sha512-x4FEgaz3zNRtJfLFqJmHWxkMDDvXVtaznj2V9jiP8ACUJrUgist4bP9FmDL2Vew2Y9mEQI/tG4GqabaitYp9CQ==", - "optional": true - }, - "faye-websocket": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", - "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "requires": { - "bser": "2.1.1" - } - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "firebase": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-7.8.0.tgz", - "integrity": "sha512-oOXb8asc9mF+xN3nHUnt8cFDo4sDkSuTSLRmPM3Jpz6yriBHJYuO1k7G6sbJOtCVl+nkj0maIyByNVQxt2eBlA==", - "requires": { - "@firebase/analytics": "0.2.12", - "@firebase/app": "0.5.3", - "@firebase/app-types": "0.5.0", - "@firebase/auth": "0.13.4", - "@firebase/database": "0.5.20", - "@firebase/firestore": "1.10.0", - "@firebase/functions": "0.4.31", - "@firebase/installations": "0.4.1", - "@firebase/messaging": "0.6.3", - "@firebase/performance": "0.2.31", - "@firebase/polyfill": "0.3.31", - "@firebase/remote-config": "0.1.12", - "@firebase/storage": "0.3.25", - "@firebase/util": "0.2.39" - } - }, - "firebase-admin": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-8.9.2.tgz", - "integrity": "sha512-ix4qcx+hHnr3mnc41Z8EzQa9Mr+2nhogLEv6ktkOCCpdKJ+9HxW9vikRCElSbC8ICHLD0KIH0GVOIZK80vbvqw==", - "requires": { - "@firebase/database": "^0.5.17", - "@google-cloud/firestore": "^3.0.0", - "@google-cloud/storage": "^4.1.2", - "@types/node": "^8.10.59", - "dicer": "^0.3.0", - "jsonwebtoken": "8.1.0", - "node-forge": "0.7.4" - }, - "dependencies": { - "@types/node": { - "version": "8.10.59", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.59.tgz", - "integrity": "sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ==" - } - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" - }, - "form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "requires": { - "map-cache": "^0.2.2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "optional": true - }, - "gaxios": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-2.3.2.tgz", - "integrity": "sha512-K/+py7UvKRDaEwEKlLiRKrFr+wjGjsMz5qH7Vs549QJS7cpSCOT/BbWL7pzqECflc46FcNPipjSfB+V1m8PAhw==", - "optional": true, - "requires": { - "abort-controller": "^3.0.0", - "extend": "^3.0.2", - "https-proxy-agent": "^5.0.0", - "is-stream": "^2.0.0", - "node-fetch": "^2.3.0" - }, - "dependencies": { - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "optional": true - }, - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", - "optional": true - } - } - }, - "gcp-metadata": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-3.5.0.tgz", - "integrity": "sha512-ZQf+DLZ5aKcRpLzYUyBS3yo3N0JSa82lNDO8rj3nMSlovLcz2riKFBsYgDzeXcv75oo5eqB2lx+B14UvPoCRnA==", - "optional": true, - "requires": { - "gaxios": "^2.1.0", - "json-bigint": "^0.3.0" - } - }, - "gcs-resumable-upload": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-2.3.2.tgz", - "integrity": "sha512-OPS0iAmPCV+r7PziOIhyxmQOzsazFCy76yYDOS/Z80O/7cuny1KMfqDQa2T0jLaL8EreTU7EMZG5pUuqBKgzHA==", - "optional": true, - "requires": { - "abort-controller": "^3.0.0", - "configstore": "^5.0.0", - "gaxios": "^2.0.0", - "google-auth-library": "^5.0.0", - "pumpify": "^2.0.0", - "stream-events": "^1.0.4" - } - }, - "gensync": { - "version": "1.0.0-beta.1", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", - "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==" - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "requires": { - "assert-plus": "^1.0.0" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "google-auth-library": { - "version": "5.10.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-5.10.1.tgz", - "integrity": "sha512-rOlaok5vlpV9rSiUu5EpR0vVpc+PhN62oF4RyX/6++DG1VsaulAFEMlDYBLjJDDPI6OcNOCGAKy9UVB/3NIDXg==", - "optional": true, - "requires": { - "arrify": "^2.0.0", - "base64-js": "^1.3.0", - "ecdsa-sig-formatter": "^1.0.11", - "fast-text-encoding": "^1.0.0", - "gaxios": "^2.1.0", - "gcp-metadata": "^3.4.0", - "gtoken": "^4.1.0", - "jws": "^4.0.0", - "lru-cache": "^5.0.0" - } - }, - "google-gax": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-1.14.2.tgz", - "integrity": "sha512-Nde+FdqALbV3QgMA4KlkxOHfrj9busnZ3EECwy/1gDJm9vhKGwDLWzErqRU5g80OoGSAMgyY7DWIfqz7ina4Jw==", - "optional": true, - "requires": { - "@grpc/grpc-js": "^0.6.18", - "@grpc/proto-loader": "^0.5.1", - "@types/fs-extra": "^8.0.1", - "@types/long": "^4.0.0", - "abort-controller": "^3.0.0", - "duplexify": "^3.6.0", - "google-auth-library": "^5.0.0", - "is-stream-ended": "^0.1.4", - "lodash.at": "^4.6.0", - "lodash.has": "^4.5.2", - "node-fetch": "^2.6.0", - "protobufjs": "^6.8.8", - "retry-request": "^4.0.0", - "semver": "^6.0.0", - "walkdir": "^0.4.0" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", - "optional": true - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true - } - } - }, - "google-p12-pem": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-2.0.4.tgz", - "integrity": "sha512-S4blHBQWZRnEW44OcR7TL9WR+QCqByRvhNDZ/uuQfpxywfupikf/miba8js1jZi6ZOGv5slgSuoshCWh6EMDzg==", - "optional": true, - "requires": { - "node-forge": "^0.9.0" - }, - "dependencies": { - "node-forge": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.1.tgz", - "integrity": "sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ==", - "optional": true - } - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", - "optional": true - }, - "grpc": { - "version": "1.24.2", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.2.tgz", - "integrity": "sha512-EG3WH6AWMVvAiV15d+lr+K77HJ/KV/3FvMpjKjulXHbTwgDZkhkcWbwhxFAoTdxTkQvy0WFcO3Nog50QBbHZWw==", - "requires": { - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "node-pre-gyp": "^0.14.0", - "protobufjs": "^5.0.3" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.3", - "bundled": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true - }, - "debug": { - "version": "3.2.6", - "bundled": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true - }, - "fs-minipass": { - "version": "1.2.7", - "bundled": true, - "requires": { - "minipass": "^2.6.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.4", - "bundled": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.3", - "bundled": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "bundled": true - }, - "ini": { - "version": "1.3.5", - "bundled": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "1.2.0", - "bundled": true - }, - "minipass": { - "version": "2.9.0", - "bundled": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "bundled": true, - "requires": { - "minipass": "^2.9.0" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "bundled": true - } - } - }, - "ms": { - "version": "2.1.2", - "bundled": true - }, - "needle": { - "version": "2.4.0", - "bundled": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.14.0", - "bundled": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true - }, - "npm-packlist": { - "version": "1.4.6", - "bundled": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true - }, - "process-nextick-args": { - "version": "2.0.1", - "bundled": true - }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.7.1", - "bundled": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true - }, - "sax": { - "version": "1.2.4", - "bundled": true - }, - "semver": { - "version": "5.7.1", - "bundled": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true - }, - "tar": { - "version": "4.4.13", - "bundled": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.8.6", - "minizlib": "^1.2.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.3" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "yallist": { - "version": "3.1.1", - "bundled": true - } - } - }, - "gtoken": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-4.1.4.tgz", - "integrity": "sha512-VxirzD0SWoFUo5p8RDP8Jt2AGyOmyYcT/pOUgDKJCK+iSw0TMqwrVfY37RXTNmoKwrzmDHSk0GMT9FsgVmnVSA==", - "optional": true, - "requires": { - "gaxios": "^2.1.0", - "google-p12-pem": "^2.0.0", - "jws": "^4.0.0", - "mime": "^2.2.0" - } - }, - "har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" - }, - "har-validator": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", - "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", - "requires": { - "ajv": "^6.5.5", - "har-schema": "^2.0.0" - } - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==" - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-stream-validation": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.2.tgz", - "integrity": "sha512-cMlva5CxWZOrlS/cY0C+9qAzesn5srhFA8IT1VPiHc9bWWBLkJfEUIZr7MWoi89oOOGmpg8ymchaOjiArsGu5A==", - "optional": true, - "requires": { - "through2": "^2.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "optional": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "requires": { - "whatwg-encoding": "^1.0.1" - } - }, - "html-escaper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz", - "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==" - }, - "http-parser-js": { - "version": "0.4.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.10.tgz", - "integrity": "sha1-ksnBN0w1CF912zWexWzCV8u5P6Q=" - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "optional": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", - "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "optional": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==" - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "idb": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/idb/-/idb-3.0.2.tgz", - "integrity": "sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw==" - }, - "import-local": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.0.2.tgz", - "integrity": "sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==", - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" - }, - "ip-regex": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-arguments": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", - "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", - "optional": true - }, - "is-bigint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.0.tgz", - "integrity": "sha512-t5mGUXC/xRheCK431ylNiSkGGpBp8bHENBcENTkDT6ppwPzEVxNGZRvgvmOEfbWkFhA7D2GEuE2mmQTr78sl2g==", - "optional": true - }, - "is-boolean-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.0.1.tgz", - "integrity": "sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ==", - "optional": true - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", - "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==" - }, - "is-ci": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", - "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", - "requires": { - "ci-info": "^2.0.0" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", - "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==" - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==" - }, - "is-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.1.tgz", - "integrity": "sha512-T/S49scO8plUiAOA2DBTBG3JHpn1yiw0kRp6dgiZ0v2/6twi5eiB0rHtHFH9ZIrvlWc6+4O+m4zg5+Z833aXgw==", - "optional": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" - }, - "is-number-object": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.4.tgz", - "integrity": "sha512-zohwelOAur+5uXtk8O3GPQ1eAcu4ZX3UwxQhUlfFFMNpUd83gXgjbhJh6HmB6LUNV/ieOLQuDwJO3dWJosUeMw==", - "optional": true - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "optional": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", - "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", - "requires": { - "has": "^1.0.3" - } - }, - "is-set": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.1.tgz", - "integrity": "sha512-eJEzOtVyenDs1TMzSQ3kU3K+E0GUS9sno+F0OBT97xsgcJsF9nXMBtkT9/kut5JEpM7oL7X/0qxR17K3mcwIAA==", - "optional": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-stream-ended": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz", - "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==", - "optional": true - }, - "is-string": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", - "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", - "optional": true - }, - "is-symbol": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", - "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", - "requires": { - "has-symbols": "^1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" - }, - "is-weakmap": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz", - "integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==", - "optional": true - }, - "is-weakset": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.1.tgz", - "integrity": "sha512-pi4vhbhVHGLxohUw7PhGsueT4vRGFoXhP7+RGN0jKIv9+8PWYCQTqtADngrxOm2g46hoH0+g8uZZBzMrvVGDmw==", - "optional": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" - }, - "is-wsl": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.1.1.tgz", - "integrity": "sha512-umZHcSrwlDHo2TGMXv0DZ8dIUGunZ2Iv68YZnrmCiBPkZ4aaOhtv7pXJKeki9k3qJ3RJr0cDyitcl5wEH3AYog==", - "optional": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" - }, - "istanbul-lib-coverage": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", - "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==" - }, - "istanbul-lib-instrument": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.0.tgz", - "integrity": "sha512-Nm4wVHdo7ZXSG30KjZ2Wl5SU/Bw7bDx1PdaiIFzEStdjs0H12mOTncn1GVYuqQSaZxpg87VGBRsVRPGD2cD1AQ==", - "requires": { - "@babel/core": "^7.7.5", - "@babel/parser": "^7.7.5", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", - "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==", - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-25.1.0.tgz", - "integrity": "sha512-FV6jEruneBhokkt9MQk0WUFoNTwnF76CLXtwNMfsc0um0TlB/LG2yxUd0KqaFjEJ9laQmVWQWS0sG/t2GsuI0w==", - "requires": { - "@jest/core": "^25.1.0", - "import-local": "^3.0.2", - "jest-cli": "^25.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "jest-cli": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-25.1.0.tgz", - "integrity": "sha512-p+aOfczzzKdo3AsLJlhs8J5EW6ffVidfSZZxXedJ0mHPBOln1DccqFmGCoO8JWd4xRycfmwy1eoQkMsF8oekPg==", - "requires": { - "@jest/core": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "is-ci": "^2.0.0", - "jest-config": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", - "prompts": "^2.0.1", - "realpath-native": "^1.1.0", - "yargs": "^15.0.0" - } - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", - "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^16.1.0" - } - } - } - }, - "jest-changed-files": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-25.1.0.tgz", - "integrity": "sha512-bdL1aHjIVy3HaBO3eEQeemGttsq1BDlHgWcOjEOIAcga7OOEGWHD2WSu8HhL7I1F0mFFyci8VKU4tRNk+qtwDA==", - "requires": { - "@jest/types": "^25.1.0", - "execa": "^3.2.0", - "throat": "^5.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz", - "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "execa": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-3.4.0.tgz", - "integrity": "sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g==", - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "p-finally": "^2.0.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - } - }, - "get-stream": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", - "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", - "requires": { - "pump": "^3.0.0" - } - }, - "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==" - }, - "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "requires": { - "path-key": "^3.0.0" - } - }, - "p-finally": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", - "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "jest-config": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-25.1.0.tgz", - "integrity": "sha512-tLmsg4SZ5H7tuhBC5bOja0HEblM0coS3Wy5LTCb2C8ZV6eWLewHyK+3qSq9Bi29zmWQ7ojdCd3pxpx4l4d2uGw==", - "requires": { - "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^25.1.0", - "@jest/types": "^25.1.0", - "babel-jest": "^25.1.0", - "chalk": "^3.0.0", - "glob": "^7.1.1", - "jest-environment-jsdom": "^25.1.0", - "jest-environment-node": "^25.1.0", - "jest-get-type": "^25.1.0", - "jest-jasmine2": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", - "micromatch": "^4.0.2", - "pretty-format": "^25.1.0", - "realpath-native": "^1.1.0" - } - }, - "jest-diff": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.1.0.tgz", - "integrity": "sha512-nepXgajT+h017APJTreSieh4zCqnSHEJ1iT8HDlewu630lSJ4Kjjr9KNzm+kzGwwcpsDE6Snx1GJGzzsefaEHw==", - "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-docblock": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-25.1.0.tgz", - "integrity": "sha512-370P/mh1wzoef6hUKiaMcsPtIapY25suP6JqM70V9RJvdKLrV4GaGbfUseUVk4FZJw4oTZ1qSCJNdrClKt5JQA==", - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-25.1.0.tgz", - "integrity": "sha512-R9EL8xWzoPySJ5wa0DXFTj7NrzKpRD40Jy+zQDp3Qr/2QmevJgkN9GqioCGtAJ2bW9P/MQRznQHQQhoeAyra7A==", - "requires": { - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "jest-get-type": "^25.1.0", - "jest-util": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-environment-jsdom": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-25.1.0.tgz", - "integrity": "sha512-ILb4wdrwPAOHX6W82GGDUiaXSSOE274ciuov0lztOIymTChKFtC02ddyicRRCdZlB5YSrv3vzr1Z5xjpEe1OHQ==", - "requires": { - "@jest/environment": "^25.1.0", - "@jest/fake-timers": "^25.1.0", - "@jest/types": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-util": "^25.1.0", - "jsdom": "^15.1.1" - } - }, - "jest-environment-node": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-25.1.0.tgz", - "integrity": "sha512-U9kFWTtAPvhgYY5upnH9rq8qZkj6mYLup5l1caAjjx9uNnkLHN2xgZy5mo4SyLdmrh/EtB9UPpKFShvfQHD0Iw==", - "requires": { - "@jest/environment": "^25.1.0", - "@jest/fake-timers": "^25.1.0", - "@jest/types": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-util": "^25.1.0" - } - }, - "jest-get-type": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.1.0.tgz", - "integrity": "sha512-yWkBnT+5tMr8ANB6V+OjmrIJufHtCAqI5ic2H40v+tRqxDmE0PGnIiTyvRWFOMtmVHYpwRqyazDbTnhpjsGvLw==" - }, - "jest-haste-map": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-25.1.0.tgz", - "integrity": "sha512-/2oYINIdnQZAqyWSn1GTku571aAfs8NxzSErGek65Iu5o8JYb+113bZysRMcC/pjE5v9w0Yz+ldbj9NxrFyPyw==", - "requires": { - "@jest/types": "^25.1.0", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", - "graceful-fs": "^4.2.3", - "jest-serializer": "^25.1.0", - "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", - "micromatch": "^4.0.2", - "sane": "^4.0.3", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-25.1.0.tgz", - "integrity": "sha512-GdncRq7jJ7sNIQ+dnXvpKO2MyP6j3naNK41DTTjEAhLEdpImaDA9zSAZwDhijjSF/D7cf4O5fdyUApGBZleaEg==", - "requires": { - "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.1.0", - "@jest/source-map": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "co": "^4.6.0", - "expect": "^25.1.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "pretty-format": "^25.1.0", - "throat": "^5.0.0" - } - }, - "jest-leak-detector": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-25.1.0.tgz", - "integrity": "sha512-3xRI264dnhGaMHRvkFyEKpDeaRzcEBhyNrOG5oT8xPxOyUAblIAQnpiR3QXu4wDor47MDTiHbiFcbypdLcLW5w==", - "requires": { - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-matcher-utils": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-25.1.0.tgz", - "integrity": "sha512-KGOAFcSFbclXIFE7bS4C53iYobKI20ZWleAdAFun4W1Wz1Kkej8Ng6RRbhL8leaEvIOjGXhGf/a1JjO8bkxIWQ==", - "requires": { - "chalk": "^3.0.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "pretty-format": "^25.1.0" - } - }, - "jest-message-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-25.1.0.tgz", - "integrity": "sha512-Nr/Iwar2COfN22aCqX0kCVbXgn8IBm9nWf4xwGr5Olv/KZh0CZ32RKgZWMVDXGdOahicM10/fgjdimGNX/ttCQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/stack-utils": "^1.0.1", - "chalk": "^3.0.0", - "micromatch": "^4.0.2", - "slash": "^3.0.0", - "stack-utils": "^1.0.1" - } - }, - "jest-mock": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-25.1.0.tgz", - "integrity": "sha512-28/u0sqS+42vIfcd1mlcg4ZVDmSUYuNvImP4X2lX5hRMLW+CN0BeiKVD4p+ujKKbSPKd3rg/zuhCF+QBLJ4vag==", - "requires": { - "@jest/types": "^25.1.0" - } - }, - "jest-pnp-resolver": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz", - "integrity": "sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ==" - }, - "jest-regex-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-25.1.0.tgz", - "integrity": "sha512-9lShaDmDpqwg+xAd73zHydKrBbbrIi08Kk9YryBEBybQFg/lBWR/2BDjjiSE7KIppM9C5+c03XiDaZ+m4Pgs1w==" - }, - "jest-resolve": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-25.1.0.tgz", - "integrity": "sha512-XkBQaU1SRCHj2Evz2Lu4Czs+uIgJXWypfO57L7JYccmAXv4slXA6hzNblmcRmf7P3cQ1mE7fL3ABV6jAwk4foQ==", - "requires": { - "@jest/types": "^25.1.0", - "browser-resolve": "^1.11.3", - "chalk": "^3.0.0", - "jest-pnp-resolver": "^1.2.1", - "realpath-native": "^1.1.0" - } - }, - "jest-resolve-dependencies": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-25.1.0.tgz", - "integrity": "sha512-Cu/Je38GSsccNy4I2vL12ZnBlD170x2Oh1devzuM9TLH5rrnLW1x51lN8kpZLYTvzx9j+77Y5pqBaTqfdzVzrw==", - "requires": { - "@jest/types": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-snapshot": "^25.1.0" - } - }, - "jest-runner": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-25.1.0.tgz", - "integrity": "sha512-su3O5fy0ehwgt+e8Wy7A8CaxxAOCMzL4gUBftSs0Ip32S0epxyZPDov9Znvkl1nhVOJNf4UwAsnqfc3plfQH9w==", - "requires": { - "@jest/console": "^25.1.0", - "@jest/environment": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.3", - "jest-config": "^25.1.0", - "jest-docblock": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-jasmine2": "^25.1.0", - "jest-leak-detector": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-runtime": "^25.1.0", - "jest-util": "^25.1.0", - "jest-worker": "^25.1.0", - "source-map-support": "^0.5.6", - "throat": "^5.0.0" - } - }, - "jest-runtime": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-25.1.0.tgz", - "integrity": "sha512-mpPYYEdbExKBIBB16ryF6FLZTc1Rbk9Nx0ryIpIMiDDkOeGa0jQOKVI/QeGvVGlunKKm62ywcioeFVzIbK03bA==", - "requires": { - "@jest/console": "^25.1.0", - "@jest/environment": "^25.1.0", - "@jest/source-map": "^25.1.0", - "@jest/test-result": "^25.1.0", - "@jest/transform": "^25.1.0", - "@jest/types": "^25.1.0", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.3", - "jest-config": "^25.1.0", - "jest-haste-map": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-mock": "^25.1.0", - "jest-regex-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "jest-snapshot": "^25.1.0", - "jest-util": "^25.1.0", - "jest-validate": "^25.1.0", - "realpath-native": "^1.1.0", - "slash": "^3.0.0", - "strip-bom": "^4.0.0", - "yargs": "^15.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - }, - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "requires": { - "ansi-regex": "^5.0.0" - } - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" - }, - "yargs": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.1.0.tgz", - "integrity": "sha512-T39FNN1b6hCW4SOIk1XyTOWxtXdcen0t+XYrysQmChzSipvhBO8Bj0nK1ozAasdk24dNWuMZvr4k24nz+8HHLg==", - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^16.1.0" - } - } - } - }, - "jest-serializer": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-25.1.0.tgz", - "integrity": "sha512-20Wkq5j7o84kssBwvyuJ7Xhn7hdPeTXndnwIblKDR2/sy1SUm6rWWiG9kSCgJPIfkDScJCIsTtOKdlzfIHOfKA==" - }, - "jest-snapshot": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-25.1.0.tgz", - "integrity": "sha512-xZ73dFYN8b/+X2hKLXz4VpBZGIAn7muD/DAg+pXtDzDGw3iIV10jM7WiHqhCcpDZfGiKEj7/2HXAEPtHTj0P2A==", - "requires": { - "@babel/types": "^7.0.0", - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "expect": "^25.1.0", - "jest-diff": "^25.1.0", - "jest-get-type": "^25.1.0", - "jest-matcher-utils": "^25.1.0", - "jest-message-util": "^25.1.0", - "jest-resolve": "^25.1.0", - "mkdirp": "^0.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^25.1.0", - "semver": "^7.1.1" - }, - "dependencies": { - "semver": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.1.2.tgz", - "integrity": "sha512-BJs9T/H8sEVHbeigqzIEo57Iu/3DG6c4QoqTfbQB3BPA4zgzAomh/Fk9E7QtjWQ8mx2dgA9YCfSF4y9k9bHNpQ==" - } - } - }, - "jest-util": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-25.1.0.tgz", - "integrity": "sha512-7did6pLQ++87Qsj26Fs/TIwZMUFBXQ+4XXSodRNy3luch2DnRXsSnmpVtxxQ0Yd6WTipGpbhh2IFP1mq6/fQGw==", - "requires": { - "@jest/types": "^25.1.0", - "chalk": "^3.0.0", - "is-ci": "^2.0.0", - "mkdirp": "^0.5.1" - } - }, - "jest-validate": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.1.0.tgz", - "integrity": "sha512-kGbZq1f02/zVO2+t1KQGSVoCTERc5XeObLwITqC6BTRH3Adv7NZdYqCpKIZLUgpLXf2yISzQ465qOZpul8abXA==", - "requires": { - "@jest/types": "^25.1.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.1.0", - "leven": "^3.1.0", - "pretty-format": "^25.1.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - } - } - }, - "jest-watcher": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-25.1.0.tgz", - "integrity": "sha512-Q9eZ7pyaIr6xfU24OeTg4z1fUqBF/4MP6J801lyQfg7CsnZ/TCzAPvCfckKdL5dlBBEKBeHV0AdyjFZ5eWj4ig==", - "requires": { - "@jest/test-result": "^25.1.0", - "@jest/types": "^25.1.0", - "ansi-escapes": "^4.2.1", - "chalk": "^3.0.0", - "jest-util": "^25.1.0", - "string-length": "^3.1.0" - } - }, - "jest-worker": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz", - "integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==", - "requires": { - "merge-stream": "^2.0.0", - "supports-color": "^7.0.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" - }, - "jsdom": { - "version": "15.2.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.2.1.tgz", - "integrity": "sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g==", - "requires": { - "abab": "^2.0.0", - "acorn": "^7.1.0", - "acorn-globals": "^4.3.2", - "array-equal": "^1.0.0", - "cssom": "^0.4.1", - "cssstyle": "^2.0.0", - "data-urls": "^1.1.0", - "domexception": "^1.0.1", - "escodegen": "^1.11.1", - "html-encoding-sniffer": "^1.0.2", - "nwsapi": "^2.2.0", - "parse5": "5.1.0", - "pn": "^1.1.0", - "request": "^2.88.0", - "request-promise-native": "^1.0.7", - "saxes": "^3.1.9", - "symbol-tree": "^3.2.2", - "tough-cookie": "^3.0.1", - "w3c-hr-time": "^1.0.1", - "w3c-xmlserializer": "^1.1.2", - "webidl-conversions": "^4.0.2", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^7.0.0", - "ws": "^7.0.0", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { - "tough-cookie": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", - "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", - "requires": { - "ip-regex": "^2.1.0", - "psl": "^1.1.28", - "punycode": "^2.1.1" - } - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-bigint": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-0.3.0.tgz", - "integrity": "sha1-DM2RLEuCcNBfBW+9E4FLU9OCWx4=", - "optional": true, - "requires": { - "bignumber.js": "^7.0.0" - } - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonwebtoken": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.0.tgz", - "integrity": "sha1-xjl80uX9WD1lwAeoPce7eOaYK4M=", - "requires": { - "jws": "^3.1.4", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", - "ms": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "requires": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - } - } - }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - } - }, - "jwa": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz", - "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==", - "optional": true, - "requires": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "jws": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz", - "integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==", - "optional": true, - "requires": { - "jwa": "^2.0.0", - "safe-buffer": "^5.0.1" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "requires": { - "invert-kv": "^1.0.0" - } - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==" - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "lodash": { - "version": "4.17.19", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" - }, - "lodash.at": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.at/-/lodash.at-4.6.0.tgz", - "integrity": "sha1-k83OZk8KGZTqM9181A4jr9EbD/g=", - "optional": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=" - }, - "lodash.has": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz", - "integrity": "sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI=", - "optional": true - }, - "lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" - }, - "lodash.isboolean": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" - }, - "lodash.isinteger": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" - }, - "lodash.isnumber": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" - }, - "lodash.once": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" - }, - "lodash.sortby": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" - }, - "lolex": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/lolex/-/lolex-5.1.2.tgz", - "integrity": "sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A==", - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "long": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "optional": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", - "requires": { - "tmpl": "1.0.x" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "requires": { - "object-visit": "^1.0.0" - } - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" - } - }, - "mime": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz", - "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA==", - "optional": true - }, - "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" - }, - "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", - "requires": { - "mime-db": "1.43.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node-forge": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.4.tgz", - "integrity": "sha512-8Df0906+tq/omxuCZD6PqhPaQDYuyJ1d+VITgxoIA8zvQd1ru+nMJcDChHH324MWitIgbVkAkQoGEEVJNpn/PA==" - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=" - }, - "node-modules-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", - "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" - }, - "node-notifier": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-6.0.0.tgz", - "integrity": "sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw==", - "optional": true, - "requires": { - "growly": "^1.3.0", - "is-wsl": "^2.1.1", - "semver": "^6.3.0", - "shellwords": "^0.1.1", - "which": "^1.3.1" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "optional": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==" - }, - "oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", - "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==" - }, - "object-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz", - "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==", - "optional": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", - "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "requires": { - "isobject": "^3.0.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", - "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "requires": { - "lcid": "^1.0.0" - } - }, - "p-each-series": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", - "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==" - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "parse5": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", - "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" - }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, - "performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" - }, - "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==" - }, - "pirates": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz", - "integrity": "sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA==", - "requires": { - "node-modules-regexp": "^1.0.0" - } - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - } - }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=" - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" - }, - "pretty-format": { - "version": "25.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.1.0.tgz", - "integrity": "sha512-46zLRSGLd02Rp+Lhad9zzuNZ+swunitn8zIpfD2B4OPCRLXbM87RJT2aBLBWYOznNUML/2l/ReMyWNC80PJBUQ==", - "requires": { - "@jest/types": "^25.1.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" - } - } - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "optional": true - }, - "promise-polyfill": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.1.3.tgz", - "integrity": "sha512-MG5r82wBzh7pSKDRa9y+vllNHz3e3d4CNj1PQE4BQYxLme0gKYYBm9YENq+UkEikyZ0XbiGWxYlVw3Rl9O/U8g==" - }, - "prompts": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.0.tgz", - "integrity": "sha512-NfbbPPg/74fT7wk2XYQ7hAIp9zJyZp5Fu19iRbORqqy1BhtrkZ0fPafBU+7bmn8ie69DpT0R6QpJIN2oisYjJg==", - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.3" - } - }, - "protobufjs": { - "version": "6.8.8", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", - "requires": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", - "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", - "@types/long": "^4.0.0", - "@types/node": "^10.1.0", - "long": "^4.0.0" - }, - "dependencies": { - "@types/node": { - "version": "10.17.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.14.tgz", - "integrity": "sha512-G0UmX5uKEmW+ZAhmZ6PLTQ5eu/VPaT+d/tdLd5IFsKRPcbe6lPxocBtcYBFSaLaCW8O60AX90e91Nsp8lVHCNw==" - } - } - }, - "psl": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz", - "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==" - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz", - "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==", - "optional": true, - "requires": { - "duplexify": "^4.1.1", - "inherits": "^2.0.3", - "pump": "^3.0.0" - }, - "dependencies": { - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", - "optional": true, - "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==" - }, - "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "optional": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "realpath-native": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.1.0.tgz", - "integrity": "sha512-wlgPA6cCIIg9gKz0fgAPjnzh4yR/LnXovwuo9hvyGvx3h8nX4+/iLZplfUWasXpqD8BdnGnP5njOFjkUwPzvjA==", - "requires": { - "util.promisify": "^1.0.0" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", - "optional": true, - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==" - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" - }, - "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.0", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - } - } - } - }, - "request-promise-core": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz", - "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==", - "requires": { - "lodash": "^4.17.15" - } - }, - "request-promise-native": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz", - "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==", - "requires": { - "request-promise-core": "1.1.3", - "stealthy-require": "^1.1.1", - "tough-cookie": "^2.3.3" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" - }, - "resolve": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", - "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", - "requires": { - "path-parse": "^1.0.6" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "requires": { - "resolve-from": "^5.0.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==" - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" - }, - "retry-request": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.1.1.tgz", - "integrity": "sha512-BINDzVtLI2BDukjWmjAIRZ0oglnCAkpP2vQjM3jdLhmT62h0xnQgciPwBRDAvHqpkPT2Wo1XuUyLyn6nbGrZQQ==", - "optional": true, - "requires": { - "debug": "^4.1.1", - "through2": "^3.0.1" - } - }, - "rimraf": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.1.tgz", - "integrity": "sha512-IQ4ikL8SjBiEDZfk+DFVwqRK8md24RWMEJkdSlgNLkyyAImcjf8SWvU1qFMDOb4igBClbTQ/ugPqXcRwdFTxZw==", - "requires": { - "glob": "^7.1.3" - } - }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==" - }, - "safe-buffer": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", - "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "requires": { - "ret": "~0.1.10" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sane": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/sane/-/sane-4.1.0.tgz", - "integrity": "sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==", - "requires": { - "@cnakazawa/watch": "^1.0.3", - "anymatch": "^2.0.0", - "capture-exit": "^2.0.0", - "exec-sh": "^0.3.2", - "execa": "^1.0.0", - "fb-watchman": "^2.0.0", - "micromatch": "^3.1.4", - "minimist": "^1.1.1", - "walker": "~1.0.5" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "requires": { - "remove-trailing-separator": "^1.0.1" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - } - } - }, - "saxes": { - "version": "3.1.11", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", - "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", - "requires": { - "xmlchars": "^2.1.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" - }, - "shellwords": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", - "optional": true - }, - "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", - "optional": true, - "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" - } - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" - }, - "sisteransi": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.4.tgz", - "integrity": "sha512-/ekMoM4NJ59ivGSfKapeG+FWtrmWvA1p6FBZwXrqojw90vJu8lBmrTxCMuBCydKtkaUe2zt4PlxeTKpjwMbyig==" - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" - }, - "snakeize": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/snakeize/-/snakeize-0.1.0.tgz", - "integrity": "sha1-EMCI2LWOsHazIpu1oE4jLOEmQi0=", - "optional": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "requires": { - "is-extendable": "^0.1.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.5.16", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", - "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" - }, - "sshpk": { - "version": "1.16.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", - "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", - "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - } - }, - "stack-utils": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", - "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==" - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" - }, - "stream-events": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz", - "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==", - "optional": true, - "requires": { - "stubs": "^3.0.0" - } - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "optional": true - }, - "streamsearch": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", - "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" - }, - "string-length": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", - "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", - "requires": { - "astral-regex": "^1.0.0", - "strip-ansi": "^5.2.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string.prototype.trimleft": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", - "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string.prototype.trimright": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", - "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", - "requires": { - "define-properties": "^1.1.3", - "function-bind": "^1.1.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - } - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" - }, - "stubs": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz", - "integrity": "sha1-6NK6H6nJBXAwPAMLaQD31fiavls=", - "optional": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.0.0.tgz", - "integrity": "sha512-bFhn0MQ8qefLyJ3K7PpHiPUTuTVPWw6RXfaMeV6xgJLXtBbszyboz1bvGTVv4R0YpQm2DqlXXn0fFHhxUHVE5w==", - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" - }, - "teeny-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-6.0.3.tgz", - "integrity": "sha512-TZG/dfd2r6yeji19es1cUIwAlVD8y+/svB1kAC2Y0bjEyysrfbO8EZvJBRwIE6WkwmUoB7uvWLwTIhJbMXZ1Dw==", - "optional": true, - "requires": { - "http-proxy-agent": "^4.0.0", - "https-proxy-agent": "^5.0.0", - "node-fetch": "^2.2.0", - "stream-events": "^1.0.5", - "uuid": "^7.0.0" - }, - "dependencies": { - "node-fetch": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", - "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==", - "optional": true - }, - "uuid": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-7.0.2.tgz", - "integrity": "sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==", - "optional": true - } - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "requires": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "throat": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/throat/-/throat-5.0.0.tgz", - "integrity": "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA==" - }, - "through2": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", - "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", - "optional": true, - "requires": { - "readable-stream": "2 || 3" - } - }, - "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=" - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" - } - }, - "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", - "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } - } - }, - "tr46": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", - "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", - "requires": { - "punycode": "^2.1.0" - } - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "requires": { - "safe-buffer": "^5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" - }, - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "optional": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", - "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", - "optional": true, - "requires": { - "crypto-random-string": "^2.0.0" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" - } - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "optional": true - }, - "util.promisify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", - "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", - "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.2", - "has-symbols": "^1.0.1", - "object.getownpropertydescriptors": "^2.1.0" - } - }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" - }, - "v8-to-istanbul": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-4.0.1.tgz", - "integrity": "sha512-x0yZvZAkjJwdD3fPiJzYP37aod0ati4LlmD2RmpKjqewjKAov/u/ytZ8ViIZb07cN4cePKzl9ijiUi7C1LQ8hQ==", - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "dependencies": { - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" - } - } - }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "w3c-hr-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", - "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", - "requires": { - "browser-process-hrtime": "^0.1.2" - } - }, - "w3c-xmlserializer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", - "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", - "requires": { - "domexception": "^1.0.1", - "webidl-conversions": "^4.0.2", - "xml-name-validator": "^3.0.0" - } - }, - "walkdir": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", - "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==", - "optional": true - }, - "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", - "requires": { - "makeerror": "1.0.x" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" - }, - "websocket-driver": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.3.tgz", - "integrity": "sha512-bpxWlvbbB459Mlipc5GBzzZwhoZgGEZLuqPaR0INBGnPAY1vdBX6hPnoFXiw+3yWxDuHyQjO2oXTMyS8A5haFg==", - "requires": { - "http-parser-js": ">=0.4.0 <0.4.11", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "requires": { - "iconv-lite": "0.4.24" - } - }, - "whatwg-fetch": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz", - "integrity": "sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q==" - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" - }, - "whatwg-url": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz", - "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==", - "requires": { - "lodash.sortby": "^4.7.0", - "tr46": "^1.0.1", - "webidl-conversions": "^4.0.2" - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.1.tgz", - "integrity": "sha512-7BT4TwISdDGBgaemWU0N0OU7FeAEJ9Oo2P1PHRm/FCWoEi2VLWC9b6xvxAA3C/NMpxg3HXVgi0sMmGbNUbNepQ==", - "optional": true, - "requires": { - "is-bigint": "^1.0.0", - "is-boolean-object": "^1.0.0", - "is-number-object": "^1.0.3", - "is-string": "^1.0.4", - "is-symbol": "^1.0.2" - } - }, - "which-collection": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz", - "integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==", - "optional": true, - "requires": { - "is-map": "^2.0.1", - "is-set": "^2.0.1", - "is-weakmap": "^2.0.1", - "is-weakset": "^2.0.1" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" - }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" - }, - "xdg-basedir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", - "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", - "optional": true - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "xmlhttprequest": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", - "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "optional": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, - "yargs-parser": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", - "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "dependencies": { - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" - } - } - } - } -} diff --git a/041-firestore-security-rules-with-testing/compound/firebase/package.json b/041-firestore-security-rules-with-testing/compound/firebase/package.json deleted file mode 100644 index 6ac9c7b5..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "firebase", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "@firebase/testing": "^0.16.7", - "firebase-admin": "^8.9.2", - "jest": "^25.1.0" - } -} diff --git a/041-firestore-security-rules-with-testing/compound/firebase/spec/collections.spec.js b/041-firestore-security-rules-with-testing/compound/firebase/spec/collections.spec.js deleted file mode 100644 index 43f01266..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/spec/collections.spec.js +++ /dev/null @@ -1,139 +0,0 @@ -const { setup, teardown } = require("./helpers"); - -describe("General Safety Rules", () => { - afterEach(async () => { - await teardown(); - }); - - test("should deny a read to the posts collection", async () => { - const db = await setup(); - const postsRef = db.collection("posts"); - await expect(postsRef.get()).toDeny(); - }); - - test("should deny a write to users even when logged in", async () => { - const db = await setup({ - uid: "danefilled" - }); - - const usersRef = db.collection("users"); - await expect(usersRef.add({ data: "something" })).toDeny(); - }); -}); - -describe("Posts Rules", () => { - afterEach(async () => { - await teardown(); - }); - - test("should allow update when user owns post", async () => { - const mockData = { - "posts/id1": { - userId: "danefilled" - }, - "posts/id2": { - userId: "not_filledstacks" - } - }; - - const mockUser = { - uid: "danefilled" - }; - - const db = await setup(mockUser, mockData); - - const postsRef = db.collection("posts"); - - await expect( - postsRef.doc("id1").update({ updated: "new_value" }) - ).toAllow(); - - await expect(postsRef.doc("id2").update({ updated: "new_value" })).toDeny(); - }); - - test("should allow delete when user owns post", async () => { - const mockData = { - "posts/id1": { - userId: "danefilled" - }, - "posts/id2": { - userId: "not_filledstacks" - } - }; - - const mockUser = { - uid: "danefilled" - }; - - const db = await setup(mockUser, mockData); - - const postsRef = db.collection("posts"); - - await expect(postsRef.doc("id1").delete()).toAllow(); - - await expect(postsRef.doc("id2").delete()).toDeny(); - }); - - test("should allow delete when user is admin", async () => { - const mockData = { - "users/filledstacks": { - userRole: "Admin" - }, - "posts/id1": { - userId: "not_matching1" - }, - "posts/id2": { - userId: "not_matching2" - } - }; - - const mockUser = { - uid: "filledstacks" - }; - - const db = await setup(mockUser, mockData); - - const postsRef = db.collection("posts"); - - await expect(postsRef.doc("id1").delete()).toAllow(); - }); - - test("should not allow delete for normal user", async () => { - const mockData = { - "users/filledstacks": { - userRole: "User" - }, - "posts/id1": { - userId: "not_matching1" - }, - "posts/id2": { - userId: "not_matching2" - } - }; - - const mockUser = { - uid: "filledstacks" - }; - - const db = await setup(mockUser, mockData); - - const postsRef = db.collection("posts"); - - await expect(postsRef.doc("id1").delete()).toDeny(); - }); - - test("should allow adding a post when logged in", async () => { - const db = await setup({ - uid: "userId" - }); - - const postsRef = db.collection("posts"); - await expect(postsRef.add({ title: "new_post" })).toAllow(); - }); - - test("should deny adding a post when not logged in", async () => { - const db = await setup(); - const postsRef = db.collection("posts"); - await expect(postsRef.add({ title: "new post" })).toDeny(); - }); -}); diff --git a/041-firestore-security-rules-with-testing/compound/firebase/spec/helpers.js b/041-firestore-security-rules-with-testing/compound/firebase/spec/helpers.js deleted file mode 100644 index 0151266f..00000000 --- a/041-firestore-security-rules-with-testing/compound/firebase/spec/helpers.js +++ /dev/null @@ -1,79 +0,0 @@ -const firebase = require("@firebase/testing"); -const fs = require("fs"); - -module.exports.setup = async (auth, data) => { - const projectId = `rules-spec-${Date.now()}`; - - const app = firebase.initializeTestApp({ - projectId, - auth - }); - - const db = app.firestore(); - - // Apply the test rules so we can write documents - await firebase.loadFirestoreRules({ - projectId, - rules: fs.readFileSync("firestore-test.rules", "utf8") - }); - - // write mock documents if any - if (data) { - for (const key in data) { - const ref = db.doc(key); // This means the key should point directly to a document - await ref.set(data[key]); - } - } - - // Apply the actual rules for the project - await firebase.loadFirestoreRules({ - projectId, - rules: fs.readFileSync("firestore.rules", "utf8") - }); - - return db; -}; - -module.exports.teardown = async () => { - // Delete all apps currently running in the firebase simulated environment - Promise.all(firebase.apps().map(app => app.delete())); -}; - -// Add extensions onto the expect method -expect.extend({ - async toAllow(testPromise) { - let pass = false; - try { - await firebase.assertSucceeds(testPromise); - pass = true; - } catch (error) { - // log error to see which rules caused the test to fail - console.log(error); - } - - return { - pass, - message: () => - "Expected Firebase operation to be allowed, but it was denied" - }; - } -}); - -expect.extend({ - async toDeny(testPromise) { - let pass = false; - try { - await firebase.assertFails(testPromise); - pass = true; - } catch (error) { - // log error to see which rules caused the test to fail - console.log(error); - } - - return { - pass, - message: () => - "Expected Firebase operation to be denied, but it was allowed" - }; - } -}); diff --git a/041-firestore-security-rules-with-testing/compound/mobile/.flutter-plugins-dependencies b/041-firestore-security-rules-with-testing/compound/mobile/.flutter-plugins-dependencies deleted file mode 100644 index d92a2f2f..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]}],"date_created":"2020-06-18 21:49:52.289569","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/041-firestore-security-rules-with-testing/compound/mobile/.metadata b/041-firestore-security-rules-with-testing/compound/mobile/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/041-firestore-security-rules-with-testing/compound/mobile/README.md b/041-firestore-security-rules-with-testing/compound/mobile/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Bold.ttf b/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-ExtraBold.ttf b/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Light.ttf b/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Regular.ttf b/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/041-firestore-security-rules-with-testing/compound/mobile/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/041-firestore-security-rules-with-testing/compound/mobile/assets/images/icon_large.png b/041-firestore-security-rules-with-testing/compound/mobile/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/041-firestore-security-rules-with-testing/compound/mobile/assets/images/icon_large.png and /dev/null differ diff --git a/041-firestore-security-rules-with-testing/compound/mobile/assets/images/title.png b/041-firestore-security-rules-with-testing/compound/mobile/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/041-firestore-security-rules-with-testing/compound/mobile/assets/images/title.png and /dev/null differ diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/constants/route_names.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/locator.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/locator.dart deleted file mode 100644 index ab8fe4a0..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/locator.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/main.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/main.dart deleted file mode 100644 index 05de5b85..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/main.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/managers/dialog_manager.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/models/dialog_models.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/models/post.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/models/post.dart deleted file mode 100644 index 6fab34c7..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/models/post.dart +++ /dev/null @@ -1,34 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - documentId: documentId, - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/models/user.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/authentication_service.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/services/authentication_service.dart deleted file mode 100644 index d4edeb14..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/authentication_service.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - } - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/dialog_service.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/firestore_service.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/services/firestore_service.dart deleted file mode 100644 index 8704af40..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/firestore_service.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = await _postsCollectionReference.getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _postsCollectionReference.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // Add the posts onto the controller - _postsController.add(posts); - } - }); - - return _postsController.stream; - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/navigation_service.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/router.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/router.dart deleted file mode 100644 index 059f9e7c..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/router.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - var postToEdit = settings.arguments as Post; - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/app_colors.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/shared_styles.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/ui_helpers.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/create_post_view.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/create_post_view.dart deleted file mode 100644 index a61fef44..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,72 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - CreatePostView({Key key, this.edittingPost}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - child: Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ), - ) - ], - ), - )), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/home_view.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/home_view.dart deleted file mode 100644 index fcb93958..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/home_view.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: - !model.busy ? Icon(Icons.add) : CircularProgressIndicator(), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => model.deletePost(index), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/login_view.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/signup_view.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/startup_view.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/busy_button.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/busy_overlay.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/expansion_list.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/input_field.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/note_text.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/post_item.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/post_item.dart deleted file mode 100644 index 0ee1401a..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Text(post.title), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/text_link.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/base_model.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/base_model.dart deleted file mode 100644 index ac8f755b..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/create_post_view_model.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index f1abb0af..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future addPost({@required String title}) async { - setBusy(true); - - var result; - - if (!_editting) { - result = await _firestoreService - .addPost(Post(title: title, userId: currentUser.id)); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/home_view_model.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 8a47fcec..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - setBusy(true); - await _firestoreService.deletePost(_posts[index].documentId); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/login_view_model.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/login_view_model.dart deleted file mode 100644 index c3473a10..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/signup_view_model.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 25952a7f..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/startup_view_model.dart b/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 45d3e880..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - - Future handleStartUpLogic() async { - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/041-firestore-security-rules-with-testing/compound/mobile/pubspec.lock b/041-firestore-security-rules-with-testing/compound/mobile/pubspec.lock deleted file mode 100644 index 98cbfe83..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/pubspec.lock +++ /dev/null @@ -1,320 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.6" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - firebase: - dependency: transitive - description: - name: firebase - url: "https://pub.dartlang.org" - source: hosted - version: "7.2.0" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/041-firestore-security-rules-with-testing/compound/mobile/pubspec.yaml b/041-firestore-security-rules-with-testing/compound/mobile/pubspec.yaml deleted file mode 100644 index 4931eb8c..00000000 --- a/041-firestore-security-rules-with-testing/compound/mobile/pubspec.yaml +++ /dev/null @@ -1,83 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ^0.16.1 - cloud_firestore: ^0.13.6 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/042-firebase-cloud-storage/.flutter-plugins-dependencies b/042-firebase-cloud-storage/.flutter-plugins-dependencies deleted file mode 100644 index 86e172f8..00000000 --- a/042-firebase-cloud-storage/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":[]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.5/","dependencies":[]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:48:55.813376","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/042-firebase-cloud-storage/.gitignore b/042-firebase-cloud-storage/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/042-firebase-cloud-storage/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/042-firebase-cloud-storage/.metadata b/042-firebase-cloud-storage/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/042-firebase-cloud-storage/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/042-firebase-cloud-storage/README.md b/042-firebase-cloud-storage/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/042-firebase-cloud-storage/assets/fonts/OpenSans-Bold.ttf b/042-firebase-cloud-storage/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/042-firebase-cloud-storage/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/042-firebase-cloud-storage/assets/fonts/OpenSans-ExtraBold.ttf b/042-firebase-cloud-storage/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/042-firebase-cloud-storage/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/042-firebase-cloud-storage/assets/fonts/OpenSans-Light.ttf b/042-firebase-cloud-storage/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/042-firebase-cloud-storage/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/042-firebase-cloud-storage/assets/fonts/OpenSans-Regular.ttf b/042-firebase-cloud-storage/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/042-firebase-cloud-storage/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/042-firebase-cloud-storage/assets/images/icon_large.png b/042-firebase-cloud-storage/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/042-firebase-cloud-storage/assets/images/icon_large.png and /dev/null differ diff --git a/042-firebase-cloud-storage/assets/images/title.png b/042-firebase-cloud-storage/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/042-firebase-cloud-storage/assets/images/title.png and /dev/null differ diff --git a/042-firebase-cloud-storage/lib/constants/route_names.dart b/042-firebase-cloud-storage/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/042-firebase-cloud-storage/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/042-firebase-cloud-storage/lib/locator.dart b/042-firebase-cloud-storage/lib/locator.dart deleted file mode 100644 index 8b333c32..00000000 --- a/042-firebase-cloud-storage/lib/locator.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); - locator.registerLazySingleton(() => CloudStorageService()); - locator.registerLazySingleton(() => ImageSelector()); -} diff --git a/042-firebase-cloud-storage/lib/main.dart b/042-firebase-cloud-storage/lib/main.dart deleted file mode 100644 index 05de5b85..00000000 --- a/042-firebase-cloud-storage/lib/main.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/042-firebase-cloud-storage/lib/managers/dialog_manager.dart b/042-firebase-cloud-storage/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/042-firebase-cloud-storage/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/042-firebase-cloud-storage/lib/models/dialog_models.dart b/042-firebase-cloud-storage/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/042-firebase-cloud-storage/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/042-firebase-cloud-storage/lib/models/post.dart b/042-firebase-cloud-storage/lib/models/post.dart deleted file mode 100644 index 36ad43a5..00000000 --- a/042-firebase-cloud-storage/lib/models/post.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - final String imageFileName; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - this.imageFileName, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - 'imageFileName': imageFileName, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - imageFileName: map['imageFileName'], - documentId: documentId, - ); - } -} diff --git a/042-firebase-cloud-storage/lib/models/user.dart b/042-firebase-cloud-storage/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/042-firebase-cloud-storage/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/042-firebase-cloud-storage/lib/services/authentication_service.dart b/042-firebase-cloud-storage/lib/services/authentication_service.dart deleted file mode 100644 index d4edeb14..00000000 --- a/042-firebase-cloud-storage/lib/services/authentication_service.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - } - } -} diff --git a/042-firebase-cloud-storage/lib/services/cloud_storage_service.dart b/042-firebase-cloud-storage/lib/services/cloud_storage_service.dart deleted file mode 100644 index fad3c58b..00000000 --- a/042-firebase-cloud-storage/lib/services/cloud_storage_service.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; - -import 'package:firebase_storage/firebase_storage.dart'; -import 'package:flutter/foundation.dart'; - -class CloudStorageService { - Future uploadImage({ - @required File imageToUpload, - @required String title, - }) async { - var imageFileName = - title + DateTime.now().millisecondsSinceEpoch.toString(); - - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - StorageUploadTask uploadTask = firebaseStorageRef.putFile(imageToUpload); - - StorageTaskSnapshot storageSnapshot = await uploadTask.onComplete; - - var downloadUrl = await storageSnapshot.ref.getDownloadURL(); - - if (uploadTask.isComplete) { - var url = downloadUrl.toString(); - return CloudStorageResult( - imageUrl: url, - imageFileName: imageFileName, - ); - } - - return null; - } - - Future deleteImage(String imageFileName) async { - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - try { - await firebaseStorageRef.delete(); - return true; - } catch (e) { - return e.toString(); - } - } -} - -class CloudStorageResult { - final String imageUrl; - final String imageFileName; - - CloudStorageResult({this.imageUrl, this.imageFileName}); -} diff --git a/042-firebase-cloud-storage/lib/services/dialog_service.dart b/042-firebase-cloud-storage/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/042-firebase-cloud-storage/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/042-firebase-cloud-storage/lib/services/firestore_service.dart b/042-firebase-cloud-storage/lib/services/firestore_service.dart deleted file mode 100644 index 8704af40..00000000 --- a/042-firebase-cloud-storage/lib/services/firestore_service.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = await _postsCollectionReference.getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _postsCollectionReference.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // Add the posts onto the controller - _postsController.add(posts); - } - }); - - return _postsController.stream; - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } -} diff --git a/042-firebase-cloud-storage/lib/services/navigation_service.dart b/042-firebase-cloud-storage/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/042-firebase-cloud-storage/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/router.dart b/042-firebase-cloud-storage/lib/ui/router.dart deleted file mode 100644 index 059f9e7c..00000000 --- a/042-firebase-cloud-storage/lib/ui/router.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - var postToEdit = settings.arguments as Post; - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/042-firebase-cloud-storage/lib/ui/shared/app_colors.dart b/042-firebase-cloud-storage/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/042-firebase-cloud-storage/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/042-firebase-cloud-storage/lib/ui/shared/shared_styles.dart b/042-firebase-cloud-storage/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/042-firebase-cloud-storage/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/042-firebase-cloud-storage/lib/ui/shared/ui_helpers.dart b/042-firebase-cloud-storage/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/042-firebase-cloud-storage/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/042-firebase-cloud-storage/lib/ui/views/create_post_view.dart b/042-firebase-cloud-storage/lib/ui/views/create_post_view.dart deleted file mode 100644 index bc0d5d0b..00000000 --- a/042-firebase-cloud-storage/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - CreatePostView({Key key, this.edittingPost}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - GestureDetector( - // When we tap we call selectImage - onTap: () => model.selectImage(), - child: Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - // If the selected image is null we show "Tap to add post image" - child: model.selectedImage == null - ? Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ) - // If we have a selected image we want to show it - : Image.file(model.selectedImage), - ), - ) - ], - ), - )), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/views/home_view.dart b/042-firebase-cloud-storage/lib/ui/views/home_view.dart deleted file mode 100644 index fcb93958..00000000 --- a/042-firebase-cloud-storage/lib/ui/views/home_view.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: - !model.busy ? Icon(Icons.add) : CircularProgressIndicator(), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => model.deletePost(index), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/views/login_view.dart b/042-firebase-cloud-storage/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/042-firebase-cloud-storage/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/views/signup_view.dart b/042-firebase-cloud-storage/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/042-firebase-cloud-storage/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/views/startup_view.dart b/042-firebase-cloud-storage/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/042-firebase-cloud-storage/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/widgets/busy_button.dart b/042-firebase-cloud-storage/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/042-firebase-cloud-storage/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/widgets/busy_overlay.dart b/042-firebase-cloud-storage/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/042-firebase-cloud-storage/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/widgets/expansion_list.dart b/042-firebase-cloud-storage/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/042-firebase-cloud-storage/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/widgets/input_field.dart b/042-firebase-cloud-storage/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/042-firebase-cloud-storage/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/widgets/note_text.dart b/042-firebase-cloud-storage/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/042-firebase-cloud-storage/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/widgets/post_item.dart b/042-firebase-cloud-storage/lib/ui/widgets/post_item.dart deleted file mode 100644 index f8580fac..00000000 --- a/042-firebase-cloud-storage/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: post.imageUrl != null ? null : 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // If the image is not null load the imageURL - post.imageUrl != null - ? SizedBox( - height: 250, - child: CachedNetworkImage( - imageUrl: post.imageUrl, - placeholder: (context, url) => - CircularProgressIndicator(), - errorWidget: (context, url, error) => - Icon(Icons.error), - ), - ) - // If the image is null show nothing - : Container(), - Text(post.title), - ], - ), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/ui/widgets/text_link.dart b/042-firebase-cloud-storage/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/042-firebase-cloud-storage/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/042-firebase-cloud-storage/lib/utils/image_selector.dart b/042-firebase-cloud-storage/lib/utils/image_selector.dart deleted file mode 100644 index df91fc25..00000000 --- a/042-firebase-cloud-storage/lib/utils/image_selector.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -class ImageSelector { - Future selectImage() async { - return await ImagePicker().getImage(source: ImageSource.gallery); - } -} diff --git a/042-firebase-cloud-storage/lib/viewmodels/base_model.dart b/042-firebase-cloud-storage/lib/viewmodels/base_model.dart deleted file mode 100644 index ac8f755b..00000000 --- a/042-firebase-cloud-storage/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/042-firebase-cloud-storage/lib/viewmodels/create_post_view_model.dart b/042-firebase-cloud-storage/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index 8fc30517..00000000 --- a/042-firebase-cloud-storage/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'dart:io'; - -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final ImageSelector _imageSelector = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - File _selectedImage; - File get selectedImage => _selectedImage; - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future selectImage() async { - var tempImage = await _imageSelector.selectImage(); - if (tempImage != null) { - _selectedImage = File(tempImage.path); - notifyListeners(); - } - } - - Future addPost({@required String title}) async { - setBusy(true); - - CloudStorageResult storageResult; - - if (!_editting) { - storageResult = await _cloudStorageService.uploadImage( - imageToUpload: _selectedImage, - title: title, - ); - } - - var result; - - if (!_editting) { - result = await _firestoreService.addPost(Post( - title: title, - userId: currentUser.id, - imageUrl: storageResult.imageUrl, - imageFileName: storageResult.imageFileName, - )); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - imageUrl: _edittingPost.imageUrl, - imageFileName: _edittingPost.imageFileName, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/042-firebase-cloud-storage/lib/viewmodels/home_view_model.dart b/042-firebase-cloud-storage/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 4b12870e..00000000 --- a/042-firebase-cloud-storage/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - var postToDelete = _posts[index]; - setBusy(true); - await _firestoreService.deletePost(postToDelete.documentId); - // Delete the image after the post is deleted - await _cloudStorageService.deleteImage(postToDelete.imageFileName); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } -} diff --git a/042-firebase-cloud-storage/lib/viewmodels/login_view_model.dart b/042-firebase-cloud-storage/lib/viewmodels/login_view_model.dart deleted file mode 100644 index c3473a10..00000000 --- a/042-firebase-cloud-storage/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/042-firebase-cloud-storage/lib/viewmodels/signup_view_model.dart b/042-firebase-cloud-storage/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 25952a7f..00000000 --- a/042-firebase-cloud-storage/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/042-firebase-cloud-storage/lib/viewmodels/startup_view_model.dart b/042-firebase-cloud-storage/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 45d3e880..00000000 --- a/042-firebase-cloud-storage/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - - Future handleStartUpLogic() async { - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/042-firebase-cloud-storage/pubspec.lock b/042-firebase-cloud-storage/pubspec.lock deleted file mode 100644 index 24572326..00000000 --- a/042-firebase-cloud-storage/pubspec.lock +++ /dev/null @@ -1,432 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0+1" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.6" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - firebase: - dependency: transitive - description: - name: firebase - url: "https://pub.dartlang.org" - source: hosted - version: "7.2.0" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_storage: - dependency: "direct main" - description: - name: firebase_storage - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.6" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.1" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - image_picker: - dependency: "direct main" - description: - name: image_picker - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.7+2" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.24.1" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sqflite: - dependency: transitive - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.4" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/042-firebase-cloud-storage/pubspec.yaml b/042-firebase-cloud-storage/pubspec.yaml deleted file mode 100644 index 40dbb360..00000000 --- a/042-firebase-cloud-storage/pubspec.yaml +++ /dev/null @@ -1,86 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ^0.16.1 - cloud_firestore: ^0.13.6 - firebase_storage: ^3.1.6 - image_picker: ^0.6.7+2 - cached_network_image: ^2.2.0+1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/043-firebase-push-notifications/.flutter-plugins-dependencies b/043-firebase-push-notifications/.flutter-plugins-dependencies deleted file mode 100644 index 2087574d..00000000 --- a/043-firebase-push-notifications/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":[]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.5/","dependencies":[]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_messaging","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:49:23.180279","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/043-firebase-push-notifications/.gitignore b/043-firebase-push-notifications/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/043-firebase-push-notifications/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/043-firebase-push-notifications/.metadata b/043-firebase-push-notifications/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/043-firebase-push-notifications/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/043-firebase-push-notifications/README.md b/043-firebase-push-notifications/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/043-firebase-push-notifications/assets/fonts/OpenSans-Bold.ttf b/043-firebase-push-notifications/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/043-firebase-push-notifications/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/043-firebase-push-notifications/assets/fonts/OpenSans-ExtraBold.ttf b/043-firebase-push-notifications/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/043-firebase-push-notifications/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/043-firebase-push-notifications/assets/fonts/OpenSans-Light.ttf b/043-firebase-push-notifications/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/043-firebase-push-notifications/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/043-firebase-push-notifications/assets/fonts/OpenSans-Regular.ttf b/043-firebase-push-notifications/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/043-firebase-push-notifications/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/043-firebase-push-notifications/assets/images/icon_large.png b/043-firebase-push-notifications/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/043-firebase-push-notifications/assets/images/icon_large.png and /dev/null differ diff --git a/043-firebase-push-notifications/assets/images/title.png b/043-firebase-push-notifications/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/043-firebase-push-notifications/assets/images/title.png and /dev/null differ diff --git a/043-firebase-push-notifications/lib/constants/route_names.dart b/043-firebase-push-notifications/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/043-firebase-push-notifications/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/043-firebase-push-notifications/lib/locator.dart b/043-firebase-push-notifications/lib/locator.dart deleted file mode 100644 index 204b37e6..00000000 --- a/043-firebase-push-notifications/lib/locator.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); - locator.registerLazySingleton(() => CloudStorageService()); - locator.registerLazySingleton(() => ImageSelector()); - locator.registerLazySingleton(() => PushNotificationService()); -} diff --git a/043-firebase-push-notifications/lib/main.dart b/043-firebase-push-notifications/lib/main.dart deleted file mode 100644 index 05de5b85..00000000 --- a/043-firebase-push-notifications/lib/main.dart +++ /dev/null @@ -1,37 +0,0 @@ -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/043-firebase-push-notifications/lib/managers/dialog_manager.dart b/043-firebase-push-notifications/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/043-firebase-push-notifications/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/043-firebase-push-notifications/lib/models/dialog_models.dart b/043-firebase-push-notifications/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/043-firebase-push-notifications/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/043-firebase-push-notifications/lib/models/post.dart b/043-firebase-push-notifications/lib/models/post.dart deleted file mode 100644 index 36ad43a5..00000000 --- a/043-firebase-push-notifications/lib/models/post.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - final String imageFileName; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - this.imageFileName, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - 'imageFileName': imageFileName, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - imageFileName: map['imageFileName'], - documentId: documentId, - ); - } -} diff --git a/043-firebase-push-notifications/lib/models/user.dart b/043-firebase-push-notifications/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/043-firebase-push-notifications/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/043-firebase-push-notifications/lib/services/authentication_service.dart b/043-firebase-push-notifications/lib/services/authentication_service.dart deleted file mode 100644 index d4edeb14..00000000 --- a/043-firebase-push-notifications/lib/services/authentication_service.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - } - } -} diff --git a/043-firebase-push-notifications/lib/services/cloud_storage_service.dart b/043-firebase-push-notifications/lib/services/cloud_storage_service.dart deleted file mode 100644 index fad3c58b..00000000 --- a/043-firebase-push-notifications/lib/services/cloud_storage_service.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; - -import 'package:firebase_storage/firebase_storage.dart'; -import 'package:flutter/foundation.dart'; - -class CloudStorageService { - Future uploadImage({ - @required File imageToUpload, - @required String title, - }) async { - var imageFileName = - title + DateTime.now().millisecondsSinceEpoch.toString(); - - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - StorageUploadTask uploadTask = firebaseStorageRef.putFile(imageToUpload); - - StorageTaskSnapshot storageSnapshot = await uploadTask.onComplete; - - var downloadUrl = await storageSnapshot.ref.getDownloadURL(); - - if (uploadTask.isComplete) { - var url = downloadUrl.toString(); - return CloudStorageResult( - imageUrl: url, - imageFileName: imageFileName, - ); - } - - return null; - } - - Future deleteImage(String imageFileName) async { - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - try { - await firebaseStorageRef.delete(); - return true; - } catch (e) { - return e.toString(); - } - } -} - -class CloudStorageResult { - final String imageUrl; - final String imageFileName; - - CloudStorageResult({this.imageUrl, this.imageFileName}); -} diff --git a/043-firebase-push-notifications/lib/services/dialog_service.dart b/043-firebase-push-notifications/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/043-firebase-push-notifications/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/043-firebase-push-notifications/lib/services/firestore_service.dart b/043-firebase-push-notifications/lib/services/firestore_service.dart deleted file mode 100644 index 8704af40..00000000 --- a/043-firebase-push-notifications/lib/services/firestore_service.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = await _postsCollectionReference.getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _postsCollectionReference.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // Add the posts onto the controller - _postsController.add(posts); - } - }); - - return _postsController.stream; - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } -} diff --git a/043-firebase-push-notifications/lib/services/navigation_service.dart b/043-firebase-push-notifications/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/043-firebase-push-notifications/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/043-firebase-push-notifications/lib/services/push_notification_service.dart b/043-firebase-push-notifications/lib/services/push_notification_service.dart deleted file mode 100644 index a7bf9276..00000000 --- a/043-firebase-push-notifications/lib/services/push_notification_service.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:io'; - -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; - -class PushNotificationService { - final FirebaseMessaging _fcm = FirebaseMessaging(); - final NavigationService _navigationService = locator(); - - Future initialise() async { - if (Platform.isIOS) { - // request permissions if we're on android - _fcm.requestNotificationPermissions(IosNotificationSettings()); - } - - _fcm.configure( - // Called when the app is in the foreground and we receive a push notification - onMessage: (Map message) async { - print('onMessage: $message'); - }, - // Called when the app has been closed comlpetely and it's opened - // from the push notification. - onLaunch: (Map message) async { - print('onLaunch: $message'); - _serialiseAndNavigate(message); - }, - // Called when the app is in the background and it's opened - // from the push notification. - onResume: (Map message) async { - print('onResume: $message'); - _serialiseAndNavigate(message); - }, - ); - } - - void _serialiseAndNavigate(Map message) { - var notificationData = message['data']; - var view = notificationData['view']; - - if (view != null) { - // Navigate to the create post view - if (view == 'create_post') { - _navigationService.navigateTo(CreatePostViewRoute); - } - } - } -} diff --git a/043-firebase-push-notifications/lib/ui/router.dart b/043-firebase-push-notifications/lib/ui/router.dart deleted file mode 100644 index 059f9e7c..00000000 --- a/043-firebase-push-notifications/lib/ui/router.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - var postToEdit = settings.arguments as Post; - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/043-firebase-push-notifications/lib/ui/shared/app_colors.dart b/043-firebase-push-notifications/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/043-firebase-push-notifications/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/043-firebase-push-notifications/lib/ui/shared/shared_styles.dart b/043-firebase-push-notifications/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/043-firebase-push-notifications/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/043-firebase-push-notifications/lib/ui/shared/ui_helpers.dart b/043-firebase-push-notifications/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/043-firebase-push-notifications/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/043-firebase-push-notifications/lib/ui/views/create_post_view.dart b/043-firebase-push-notifications/lib/ui/views/create_post_view.dart deleted file mode 100644 index bc0d5d0b..00000000 --- a/043-firebase-push-notifications/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - CreatePostView({Key key, this.edittingPost}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - GestureDetector( - // When we tap we call selectImage - onTap: () => model.selectImage(), - child: Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - // If the selected image is null we show "Tap to add post image" - child: model.selectedImage == null - ? Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ) - // If we have a selected image we want to show it - : Image.file(model.selectedImage), - ), - ) - ], - ), - )), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/views/home_view.dart b/043-firebase-push-notifications/lib/ui/views/home_view.dart deleted file mode 100644 index fcb93958..00000000 --- a/043-firebase-push-notifications/lib/ui/views/home_view.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: - !model.busy ? Icon(Icons.add) : CircularProgressIndicator(), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => model.deletePost(index), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/043-firebase-push-notifications/lib/ui/views/login_view.dart b/043-firebase-push-notifications/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/043-firebase-push-notifications/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/views/signup_view.dart b/043-firebase-push-notifications/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/043-firebase-push-notifications/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/views/startup_view.dart b/043-firebase-push-notifications/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/043-firebase-push-notifications/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/widgets/busy_button.dart b/043-firebase-push-notifications/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/043-firebase-push-notifications/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/widgets/busy_overlay.dart b/043-firebase-push-notifications/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/043-firebase-push-notifications/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/043-firebase-push-notifications/lib/ui/widgets/expansion_list.dart b/043-firebase-push-notifications/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/043-firebase-push-notifications/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/widgets/input_field.dart b/043-firebase-push-notifications/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/043-firebase-push-notifications/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/widgets/note_text.dart b/043-firebase-push-notifications/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/043-firebase-push-notifications/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/widgets/post_item.dart b/043-firebase-push-notifications/lib/ui/widgets/post_item.dart deleted file mode 100644 index f8580fac..00000000 --- a/043-firebase-push-notifications/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: post.imageUrl != null ? null : 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // If the image is not null load the imageURL - post.imageUrl != null - ? SizedBox( - height: 250, - child: CachedNetworkImage( - imageUrl: post.imageUrl, - placeholder: (context, url) => - CircularProgressIndicator(), - errorWidget: (context, url, error) => - Icon(Icons.error), - ), - ) - // If the image is null show nothing - : Container(), - Text(post.title), - ], - ), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/043-firebase-push-notifications/lib/ui/widgets/text_link.dart b/043-firebase-push-notifications/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/043-firebase-push-notifications/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/043-firebase-push-notifications/lib/utils/image_selector.dart b/043-firebase-push-notifications/lib/utils/image_selector.dart deleted file mode 100644 index df91fc25..00000000 --- a/043-firebase-push-notifications/lib/utils/image_selector.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -class ImageSelector { - Future selectImage() async { - return await ImagePicker().getImage(source: ImageSource.gallery); - } -} diff --git a/043-firebase-push-notifications/lib/viewmodels/base_model.dart b/043-firebase-push-notifications/lib/viewmodels/base_model.dart deleted file mode 100644 index ac8f755b..00000000 --- a/043-firebase-push-notifications/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/043-firebase-push-notifications/lib/viewmodels/create_post_view_model.dart b/043-firebase-push-notifications/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index 8fc30517..00000000 --- a/043-firebase-push-notifications/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,87 +0,0 @@ -import 'dart:io'; - -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final ImageSelector _imageSelector = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - File _selectedImage; - File get selectedImage => _selectedImage; - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future selectImage() async { - var tempImage = await _imageSelector.selectImage(); - if (tempImage != null) { - _selectedImage = File(tempImage.path); - notifyListeners(); - } - } - - Future addPost({@required String title}) async { - setBusy(true); - - CloudStorageResult storageResult; - - if (!_editting) { - storageResult = await _cloudStorageService.uploadImage( - imageToUpload: _selectedImage, - title: title, - ); - } - - var result; - - if (!_editting) { - result = await _firestoreService.addPost(Post( - title: title, - userId: currentUser.id, - imageUrl: storageResult.imageUrl, - imageFileName: storageResult.imageFileName, - )); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - imageUrl: _edittingPost.imageUrl, - imageFileName: _edittingPost.imageFileName, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/043-firebase-push-notifications/lib/viewmodels/home_view_model.dart b/043-firebase-push-notifications/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 4b12870e..00000000 --- a/043-firebase-push-notifications/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - var postToDelete = _posts[index]; - setBusy(true); - await _firestoreService.deletePost(postToDelete.documentId); - // Delete the image after the post is deleted - await _cloudStorageService.deleteImage(postToDelete.imageFileName); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } -} diff --git a/043-firebase-push-notifications/lib/viewmodels/login_view_model.dart b/043-firebase-push-notifications/lib/viewmodels/login_view_model.dart deleted file mode 100644 index c3473a10..00000000 --- a/043-firebase-push-notifications/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/043-firebase-push-notifications/lib/viewmodels/signup_view_model.dart b/043-firebase-push-notifications/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index 25952a7f..00000000 --- a/043-firebase-push-notifications/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/043-firebase-push-notifications/lib/viewmodels/startup_view_model.dart b/043-firebase-push-notifications/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 36d387fb..00000000 --- a/043-firebase-push-notifications/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - final PushNotificationService _pushNotificationService = - locator(); - - Future handleStartUpLogic() async { - // Register for push notifications - await _pushNotificationService.initialise(); - - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/043-firebase-push-notifications/pubspec.lock b/043-firebase-push-notifications/pubspec.lock deleted file mode 100644 index 490394e1..00000000 --- a/043-firebase-push-notifications/pubspec.lock +++ /dev/null @@ -1,439 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0+1" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.6" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.2" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.14.12" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - firebase: - dependency: transitive - description: - name: firebase - url: "https://pub.dartlang.org" - source: hosted - version: "7.2.0" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.5" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - url: "https://pub.dartlang.org" - source: hosted - version: "6.0.16" - firebase_storage: - dependency: "direct main" - description: - name: firebase_storage - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.6" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.1" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.3" - image_picker: - dependency: "direct main" - description: - name: image_picker - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.7+2" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.1+1" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.6" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.8" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0+1" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.24.1" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.0" - sqflite: - dependency: transitive - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.5" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.16" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.6" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.4" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.8" -sdks: - dart: ">=2.7.0 <3.0.0" - flutter: ">=1.16.0 <2.0.0" diff --git a/043-firebase-push-notifications/pubspec.yaml b/043-firebase-push-notifications/pubspec.yaml deleted file mode 100644 index ce9b13cf..00000000 --- a/043-firebase-push-notifications/pubspec.yaml +++ /dev/null @@ -1,87 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ^0.12.1 - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ^0.16.1 - cloud_firestore: ^0.13.6 - firebase_storage: ^3.1.6 - image_picker: ^0.6.7+2 - cached_network_image: ^2.2.0+1 - firebase_messaging: ^6.0.16 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/044-analytics-firebase/.flutter-plugins-dependencies b/044-analytics-firebase/.flutter-plugins-dependencies deleted file mode 100644 index f541a829..00000000 --- a/044-analytics-firebase/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":[]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.5/","dependencies":[]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_analytics","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_messaging","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:48:25.210656","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/044-analytics-firebase/.gitignore b/044-analytics-firebase/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/044-analytics-firebase/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/044-analytics-firebase/.metadata b/044-analytics-firebase/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/044-analytics-firebase/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/044-analytics-firebase/README.md b/044-analytics-firebase/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/044-analytics-firebase/assets/fonts/OpenSans-Bold.ttf b/044-analytics-firebase/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/044-analytics-firebase/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/044-analytics-firebase/assets/fonts/OpenSans-ExtraBold.ttf b/044-analytics-firebase/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/044-analytics-firebase/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/044-analytics-firebase/assets/fonts/OpenSans-Light.ttf b/044-analytics-firebase/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/044-analytics-firebase/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/044-analytics-firebase/assets/fonts/OpenSans-Regular.ttf b/044-analytics-firebase/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/044-analytics-firebase/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/044-analytics-firebase/assets/images/icon_large.png b/044-analytics-firebase/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/044-analytics-firebase/assets/images/icon_large.png and /dev/null differ diff --git a/044-analytics-firebase/assets/images/title.png b/044-analytics-firebase/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/044-analytics-firebase/assets/images/title.png and /dev/null differ diff --git a/044-analytics-firebase/lib/constants/route_names.dart b/044-analytics-firebase/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/044-analytics-firebase/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/044-analytics-firebase/lib/locator.dart b/044-analytics-firebase/lib/locator.dart deleted file mode 100644 index 17bf736d..00000000 --- a/044-analytics-firebase/lib/locator.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); - locator.registerLazySingleton(() => CloudStorageService()); - locator.registerLazySingleton(() => ImageSelector()); - locator.registerLazySingleton(() => PushNotificationService()); - locator.registerLazySingleton(() => AnalyticsService()); -} diff --git a/044-analytics-firebase/lib/main.dart b/044-analytics-firebase/lib/main.dart deleted file mode 100644 index ed8c71c1..00000000 --- a/044-analytics-firebase/lib/main.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - navigatorObservers: [locator().getAnalyticsObserver()], - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/044-analytics-firebase/lib/managers/dialog_manager.dart b/044-analytics-firebase/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/044-analytics-firebase/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/044-analytics-firebase/lib/models/dialog_models.dart b/044-analytics-firebase/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/044-analytics-firebase/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/044-analytics-firebase/lib/models/post.dart b/044-analytics-firebase/lib/models/post.dart deleted file mode 100644 index 36ad43a5..00000000 --- a/044-analytics-firebase/lib/models/post.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - final String imageFileName; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - this.imageFileName, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - 'imageFileName': imageFileName, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - imageFileName: map['imageFileName'], - documentId: documentId, - ); - } -} diff --git a/044-analytics-firebase/lib/models/user.dart b/044-analytics-firebase/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/044-analytics-firebase/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/044-analytics-firebase/lib/services/analytics_service.dart b/044-analytics-firebase/lib/services/analytics_service.dart deleted file mode 100644 index 7139155b..00000000 --- a/044-analytics-firebase/lib/services/analytics_service.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:firebase_analytics/firebase_analytics.dart'; -import 'package:firebase_analytics/observer.dart'; -import 'package:flutter/foundation.dart'; - -class AnalyticsService { - final FirebaseAnalytics _analytics = FirebaseAnalytics(); - - FirebaseAnalyticsObserver getAnalyticsObserver() => - FirebaseAnalyticsObserver(analytics: _analytics); - - // User properties tells us what the user is - Future setUserProperties({@required String userId, String userRole}) async { - await _analytics.setUserId(userId); - await _analytics.setUserProperty(name: 'user_role', value: userRole); - // property to indicate if it's a pro paying member - // property that might tell us it's a regular poster, etc - } - - Future logLogin() async { - await _analytics.logLogin(loginMethod: 'email'); - } - - Future logSignUp() async { - await _analytics.logSignUp(signUpMethod: 'email'); - } - - Future logPostCreated({bool hasImage}) async { - await _analytics.logEvent( - name: 'create_post', - parameters: {'has_image': hasImage}, - ); - } -} diff --git a/044-analytics-firebase/lib/services/authentication_service.dart b/044-analytics-firebase/lib/services/authentication_service.dart deleted file mode 100644 index 130d74a6..00000000 --- a/044-analytics-firebase/lib/services/authentication_service.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - final AnalyticsService _analyticsService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - await _analyticsService.setUserProperties( - userId: authResult.user.uid, - userRole: _currentUser.userRole, - ); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - await _analyticsService.setUserProperties( - userId: user.uid, - userRole: _currentUser.userRole, - ); - } - } -} diff --git a/044-analytics-firebase/lib/services/cloud_storage_service.dart b/044-analytics-firebase/lib/services/cloud_storage_service.dart deleted file mode 100644 index fad3c58b..00000000 --- a/044-analytics-firebase/lib/services/cloud_storage_service.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; - -import 'package:firebase_storage/firebase_storage.dart'; -import 'package:flutter/foundation.dart'; - -class CloudStorageService { - Future uploadImage({ - @required File imageToUpload, - @required String title, - }) async { - var imageFileName = - title + DateTime.now().millisecondsSinceEpoch.toString(); - - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - StorageUploadTask uploadTask = firebaseStorageRef.putFile(imageToUpload); - - StorageTaskSnapshot storageSnapshot = await uploadTask.onComplete; - - var downloadUrl = await storageSnapshot.ref.getDownloadURL(); - - if (uploadTask.isComplete) { - var url = downloadUrl.toString(); - return CloudStorageResult( - imageUrl: url, - imageFileName: imageFileName, - ); - } - - return null; - } - - Future deleteImage(String imageFileName) async { - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - try { - await firebaseStorageRef.delete(); - return true; - } catch (e) { - return e.toString(); - } - } -} - -class CloudStorageResult { - final String imageUrl; - final String imageFileName; - - CloudStorageResult({this.imageUrl, this.imageFileName}); -} diff --git a/044-analytics-firebase/lib/services/dialog_service.dart b/044-analytics-firebase/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/044-analytics-firebase/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/044-analytics-firebase/lib/services/firestore_service.dart b/044-analytics-firebase/lib/services/firestore_service.dart deleted file mode 100644 index 8704af40..00000000 --- a/044-analytics-firebase/lib/services/firestore_service.dart +++ /dev/null @@ -1,111 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = await _postsCollectionReference.getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _postsCollectionReference.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // Add the posts onto the controller - _postsController.add(posts); - } - }); - - return _postsController.stream; - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } -} diff --git a/044-analytics-firebase/lib/services/navigation_service.dart b/044-analytics-firebase/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/044-analytics-firebase/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/044-analytics-firebase/lib/services/push_notification_service.dart b/044-analytics-firebase/lib/services/push_notification_service.dart deleted file mode 100644 index a7bf9276..00000000 --- a/044-analytics-firebase/lib/services/push_notification_service.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:io'; - -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; - -class PushNotificationService { - final FirebaseMessaging _fcm = FirebaseMessaging(); - final NavigationService _navigationService = locator(); - - Future initialise() async { - if (Platform.isIOS) { - // request permissions if we're on android - _fcm.requestNotificationPermissions(IosNotificationSettings()); - } - - _fcm.configure( - // Called when the app is in the foreground and we receive a push notification - onMessage: (Map message) async { - print('onMessage: $message'); - }, - // Called when the app has been closed comlpetely and it's opened - // from the push notification. - onLaunch: (Map message) async { - print('onLaunch: $message'); - _serialiseAndNavigate(message); - }, - // Called when the app is in the background and it's opened - // from the push notification. - onResume: (Map message) async { - print('onResume: $message'); - _serialiseAndNavigate(message); - }, - ); - } - - void _serialiseAndNavigate(Map message) { - var notificationData = message['data']; - var view = notificationData['view']; - - if (view != null) { - // Navigate to the create post view - if (view == 'create_post') { - _navigationService.navigateTo(CreatePostViewRoute); - } - } - } -} diff --git a/044-analytics-firebase/lib/ui/router.dart b/044-analytics-firebase/lib/ui/router.dart deleted file mode 100644 index 059f9e7c..00000000 --- a/044-analytics-firebase/lib/ui/router.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - var postToEdit = settings.arguments as Post; - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/044-analytics-firebase/lib/ui/shared/app_colors.dart b/044-analytics-firebase/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/044-analytics-firebase/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/044-analytics-firebase/lib/ui/shared/shared_styles.dart b/044-analytics-firebase/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/044-analytics-firebase/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/044-analytics-firebase/lib/ui/shared/ui_helpers.dart b/044-analytics-firebase/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/044-analytics-firebase/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/044-analytics-firebase/lib/ui/views/create_post_view.dart b/044-analytics-firebase/lib/ui/views/create_post_view.dart deleted file mode 100644 index bc0d5d0b..00000000 --- a/044-analytics-firebase/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - CreatePostView({Key key, this.edittingPost}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - GestureDetector( - // When we tap we call selectImage - onTap: () => model.selectImage(), - child: Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - // If the selected image is null we show "Tap to add post image" - child: model.selectedImage == null - ? Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ) - // If we have a selected image we want to show it - : Image.file(model.selectedImage), - ), - ) - ], - ), - )), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/views/home_view.dart b/044-analytics-firebase/lib/ui/views/home_view.dart deleted file mode 100644 index fcb93958..00000000 --- a/044-analytics-firebase/lib/ui/views/home_view.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: - !model.busy ? Icon(Icons.add) : CircularProgressIndicator(), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => model.deletePost(index), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/044-analytics-firebase/lib/ui/views/login_view.dart b/044-analytics-firebase/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/044-analytics-firebase/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/views/signup_view.dart b/044-analytics-firebase/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/044-analytics-firebase/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/views/startup_view.dart b/044-analytics-firebase/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/044-analytics-firebase/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/widgets/busy_button.dart b/044-analytics-firebase/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/044-analytics-firebase/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/widgets/busy_overlay.dart b/044-analytics-firebase/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/044-analytics-firebase/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/044-analytics-firebase/lib/ui/widgets/expansion_list.dart b/044-analytics-firebase/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/044-analytics-firebase/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/widgets/input_field.dart b/044-analytics-firebase/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/044-analytics-firebase/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/044-analytics-firebase/lib/ui/widgets/note_text.dart b/044-analytics-firebase/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/044-analytics-firebase/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/widgets/post_item.dart b/044-analytics-firebase/lib/ui/widgets/post_item.dart deleted file mode 100644 index f8580fac..00000000 --- a/044-analytics-firebase/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: post.imageUrl != null ? null : 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // If the image is not null load the imageURL - post.imageUrl != null - ? SizedBox( - height: 250, - child: CachedNetworkImage( - imageUrl: post.imageUrl, - placeholder: (context, url) => - CircularProgressIndicator(), - errorWidget: (context, url, error) => - Icon(Icons.error), - ), - ) - // If the image is null show nothing - : Container(), - Text(post.title), - ], - ), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/044-analytics-firebase/lib/ui/widgets/text_link.dart b/044-analytics-firebase/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/044-analytics-firebase/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/044-analytics-firebase/lib/utils/image_selector.dart b/044-analytics-firebase/lib/utils/image_selector.dart deleted file mode 100644 index df91fc25..00000000 --- a/044-analytics-firebase/lib/utils/image_selector.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -class ImageSelector { - Future selectImage() async { - return await ImagePicker().getImage(source: ImageSource.gallery); - } -} diff --git a/044-analytics-firebase/lib/viewmodels/base_model.dart b/044-analytics-firebase/lib/viewmodels/base_model.dart deleted file mode 100644 index ac8f755b..00000000 --- a/044-analytics-firebase/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/044-analytics-firebase/lib/viewmodels/create_post_view_model.dart b/044-analytics-firebase/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index f84026f0..00000000 --- a/044-analytics-firebase/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:io'; - -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final ImageSelector _imageSelector = locator(); - final CloudStorageService _cloudStorageService = - locator(); - final AnalyticsService _analyticsService = locator(); - - File _selectedImage; - File get selectedImage => _selectedImage; - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future selectImage() async { - var tempImage = await _imageSelector.selectImage(); - if (tempImage != null) { - _selectedImage = File(tempImage.path); - notifyListeners(); - } - } - - Future addPost({@required String title}) async { - setBusy(true); - - CloudStorageResult storageResult; - - if (!_editting) { - storageResult = await _cloudStorageService.uploadImage( - imageToUpload: _selectedImage, - title: title, - ); - } - - var result; - - if (!_editting) { - result = await _firestoreService.addPost(Post( - title: title, - userId: currentUser.id, - imageUrl: storageResult.imageUrl, - imageFileName: storageResult.imageFileName, - )); - - await _analyticsService.logPostCreated(hasImage: _selectedImage != null); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - imageUrl: _edittingPost.imageUrl, - imageFileName: _edittingPost.imageFileName, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/044-analytics-firebase/lib/viewmodels/home_view_model.dart b/044-analytics-firebase/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 4b12870e..00000000 --- a/044-analytics-firebase/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,60 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - var postToDelete = _posts[index]; - setBusy(true); - await _firestoreService.deletePost(postToDelete.documentId); - // Delete the image after the post is deleted - await _cloudStorageService.deleteImage(postToDelete.imageFileName); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } -} diff --git a/044-analytics-firebase/lib/viewmodels/login_view_model.dart b/044-analytics-firebase/lib/viewmodels/login_view_model.dart deleted file mode 100644 index a557a91a..00000000 --- a/044-analytics-firebase/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logLogin(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/044-analytics-firebase/lib/viewmodels/signup_view_model.dart b/044-analytics-firebase/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index b23ed4d2..00000000 --- a/044-analytics-firebase/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logSignUp(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/044-analytics-firebase/lib/viewmodels/startup_view_model.dart b/044-analytics-firebase/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 36d387fb..00000000 --- a/044-analytics-firebase/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - final PushNotificationService _pushNotificationService = - locator(); - - Future handleStartUpLogic() async { - // Register for push notifications - await _pushNotificationService.initialise(); - - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/044-analytics-firebase/pubspec.lock b/044-analytics-firebase/pubspec.lock deleted file mode 100644 index 53ef17ac..00000000 --- a/044-analytics-firebase/pubspec.lock +++ /dev/null @@ -1,607 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.10" - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.3" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "5.9.1" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - cross_file: - dependency: transitive - description: - name: cross_file - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.3+2" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.4" - firebase_analytics: - dependency: "direct main" - description: - name: firebase_analytics - url: "https://pub.dartlang.org" - source: hosted - version: "5.0.15" - firebase_analytics_platform_interface: - dependency: transitive - description: - name: firebase_analytics_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "6.11.4" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.5.2" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - url: "https://pub.dartlang.org" - source: hosted - version: "14.1.4" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.8" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.9" - firebase_storage: - dependency: "direct main" - description: - name: firebase_storage - url: "https://pub.dartlang.org" - source: hosted - version: "11.0.7" - firebase_storage_platform_interface: - dependency: transitive - description: - name: firebase_storage_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.25" - firebase_storage_web: - dependency: transitive - description: - name: firebase_storage_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.17" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.7" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - image_picker: - dependency: "direct main" - description: - name: image_picker - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6" - image_picker_android: - dependency: transitive - description: - name: image_picker_android - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.5+3" - image_picker_for_web: - dependency: transitive - description: - name: image_picker_for_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.10" - image_picker_ios: - dependency: transitive - description: - name: image_picker_ios - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6+1" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.6.2" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.17.0" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - octo_image: - dependency: transitive - description: - name: octo_image - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.22" - path_provider_ios: - dependency: transitive - description: - name: path_provider_ios - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.6" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.1" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.27.7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - sqflite: - dependency: transitive - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0+2" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0+3" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.2" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" -sdks: - dart: ">=2.18.0 <3.0.0" - flutter: ">=3.3.0" diff --git a/044-analytics-firebase/pubspec.yaml b/044-analytics-firebase/pubspec.yaml deleted file mode 100644 index 05f2a189..00000000 --- a/044-analytics-firebase/pubspec.yaml +++ /dev/null @@ -1,88 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ">=0.12.1 <0.14.0" - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ">=0.16.1 <5.0.0" - cloud_firestore: ">=0.13.6 <5.0.0" - firebase_storage: ">=3.1.6 <12.0.0" - image_picker: ">=0.6.7+2 <0.9.0" - cached_network_image: ">=2.2.0+1 <4.0.0" - firebase_messaging: ">=6.0.16 <15.0.0" - firebase_analytics: ^5.0.15 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/045-paginated-realtime-firestore/.flutter-plugins-dependencies b/045-paginated-realtime-firestore/.flutter-plugins-dependencies deleted file mode 100644 index 433ef678..00000000 --- a/045-paginated-realtime-firestore/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":[]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.5/","dependencies":[]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_analytics","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_messaging","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:49:43.487300","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/045-paginated-realtime-firestore/.gitignore b/045-paginated-realtime-firestore/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/045-paginated-realtime-firestore/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/045-paginated-realtime-firestore/.metadata b/045-paginated-realtime-firestore/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/045-paginated-realtime-firestore/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/045-paginated-realtime-firestore/README.md b/045-paginated-realtime-firestore/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/045-paginated-realtime-firestore/assets/fonts/OpenSans-Bold.ttf b/045-paginated-realtime-firestore/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/045-paginated-realtime-firestore/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/045-paginated-realtime-firestore/assets/fonts/OpenSans-ExtraBold.ttf b/045-paginated-realtime-firestore/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/045-paginated-realtime-firestore/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/045-paginated-realtime-firestore/assets/fonts/OpenSans-Light.ttf b/045-paginated-realtime-firestore/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/045-paginated-realtime-firestore/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/045-paginated-realtime-firestore/assets/fonts/OpenSans-Regular.ttf b/045-paginated-realtime-firestore/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/045-paginated-realtime-firestore/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/045-paginated-realtime-firestore/assets/images/icon_large.png b/045-paginated-realtime-firestore/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/045-paginated-realtime-firestore/assets/images/icon_large.png and /dev/null differ diff --git a/045-paginated-realtime-firestore/assets/images/title.png b/045-paginated-realtime-firestore/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/045-paginated-realtime-firestore/assets/images/title.png and /dev/null differ diff --git a/045-paginated-realtime-firestore/lib/constants/route_names.dart b/045-paginated-realtime-firestore/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/045-paginated-realtime-firestore/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/045-paginated-realtime-firestore/lib/locator.dart b/045-paginated-realtime-firestore/lib/locator.dart deleted file mode 100644 index 17bf736d..00000000 --- a/045-paginated-realtime-firestore/lib/locator.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); - locator.registerLazySingleton(() => CloudStorageService()); - locator.registerLazySingleton(() => ImageSelector()); - locator.registerLazySingleton(() => PushNotificationService()); - locator.registerLazySingleton(() => AnalyticsService()); -} diff --git a/045-paginated-realtime-firestore/lib/main.dart b/045-paginated-realtime-firestore/lib/main.dart deleted file mode 100644 index ed8c71c1..00000000 --- a/045-paginated-realtime-firestore/lib/main.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - navigatorObservers: [locator().getAnalyticsObserver()], - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/managers/dialog_manager.dart b/045-paginated-realtime-firestore/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/045-paginated-realtime-firestore/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/045-paginated-realtime-firestore/lib/models/dialog_models.dart b/045-paginated-realtime-firestore/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/045-paginated-realtime-firestore/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/045-paginated-realtime-firestore/lib/models/post.dart b/045-paginated-realtime-firestore/lib/models/post.dart deleted file mode 100644 index 36ad43a5..00000000 --- a/045-paginated-realtime-firestore/lib/models/post.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - final String imageFileName; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - this.imageFileName, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - 'imageFileName': imageFileName, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - imageFileName: map['imageFileName'], - documentId: documentId, - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/models/user.dart b/045-paginated-realtime-firestore/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/045-paginated-realtime-firestore/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/045-paginated-realtime-firestore/lib/services/analytics_service.dart b/045-paginated-realtime-firestore/lib/services/analytics_service.dart deleted file mode 100644 index 7139155b..00000000 --- a/045-paginated-realtime-firestore/lib/services/analytics_service.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:firebase_analytics/firebase_analytics.dart'; -import 'package:firebase_analytics/observer.dart'; -import 'package:flutter/foundation.dart'; - -class AnalyticsService { - final FirebaseAnalytics _analytics = FirebaseAnalytics(); - - FirebaseAnalyticsObserver getAnalyticsObserver() => - FirebaseAnalyticsObserver(analytics: _analytics); - - // User properties tells us what the user is - Future setUserProperties({@required String userId, String userRole}) async { - await _analytics.setUserId(userId); - await _analytics.setUserProperty(name: 'user_role', value: userRole); - // property to indicate if it's a pro paying member - // property that might tell us it's a regular poster, etc - } - - Future logLogin() async { - await _analytics.logLogin(loginMethod: 'email'); - } - - Future logSignUp() async { - await _analytics.logSignUp(signUpMethod: 'email'); - } - - Future logPostCreated({bool hasImage}) async { - await _analytics.logEvent( - name: 'create_post', - parameters: {'has_image': hasImage}, - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/services/authentication_service.dart b/045-paginated-realtime-firestore/lib/services/authentication_service.dart deleted file mode 100644 index 130d74a6..00000000 --- a/045-paginated-realtime-firestore/lib/services/authentication_service.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - final AnalyticsService _analyticsService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - await _analyticsService.setUserProperties( - userId: authResult.user.uid, - userRole: _currentUser.userRole, - ); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - await _analyticsService.setUserProperties( - userId: user.uid, - userRole: _currentUser.userRole, - ); - } - } -} diff --git a/045-paginated-realtime-firestore/lib/services/cloud_storage_service.dart b/045-paginated-realtime-firestore/lib/services/cloud_storage_service.dart deleted file mode 100644 index fad3c58b..00000000 --- a/045-paginated-realtime-firestore/lib/services/cloud_storage_service.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; - -import 'package:firebase_storage/firebase_storage.dart'; -import 'package:flutter/foundation.dart'; - -class CloudStorageService { - Future uploadImage({ - @required File imageToUpload, - @required String title, - }) async { - var imageFileName = - title + DateTime.now().millisecondsSinceEpoch.toString(); - - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - StorageUploadTask uploadTask = firebaseStorageRef.putFile(imageToUpload); - - StorageTaskSnapshot storageSnapshot = await uploadTask.onComplete; - - var downloadUrl = await storageSnapshot.ref.getDownloadURL(); - - if (uploadTask.isComplete) { - var url = downloadUrl.toString(); - return CloudStorageResult( - imageUrl: url, - imageFileName: imageFileName, - ); - } - - return null; - } - - Future deleteImage(String imageFileName) async { - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - try { - await firebaseStorageRef.delete(); - return true; - } catch (e) { - return e.toString(); - } - } -} - -class CloudStorageResult { - final String imageUrl; - final String imageFileName; - - CloudStorageResult({this.imageUrl, this.imageFileName}); -} diff --git a/045-paginated-realtime-firestore/lib/services/dialog_service.dart b/045-paginated-realtime-firestore/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/045-paginated-realtime-firestore/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/045-paginated-realtime-firestore/lib/services/firestore_service.dart b/045-paginated-realtime-firestore/lib/services/firestore_service.dart deleted file mode 100644 index 7f845889..00000000 --- a/045-paginated-realtime-firestore/lib/services/firestore_service.dart +++ /dev/null @@ -1,166 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - // #6: Create a list that will keep the paged results - List> _allPagedResults = List>(); - - static const int PostsLimit = 20; - - DocumentSnapshot _lastDocument; - bool _hasMorePosts = true; - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = - await _postsCollectionReference.limit(PostsLimit).getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _requestPosts(); - return _postsController.stream; - } - - // #1: Move the request posts into it's own function - void _requestPosts() { - // #2: split the query from the actual subscription - var pagePostsQuery = _postsCollectionReference - .orderBy('title') - // #3: Limit the amount of results - .limit(PostsLimit); - - // #5: If we have a document start the query after it - if (_lastDocument != null) { - pagePostsQuery = pagePostsQuery.startAfterDocument(_lastDocument); - } - - if (!_hasMorePosts) return; - - // #7: Get and store the page index that the results belong to - var currentRequestIndex = _allPagedResults.length; - - pagePostsQuery.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // #8: Check if the page exists or not - var pageExists = currentRequestIndex < _allPagedResults.length; - - // #9: If the page exists update the posts for that page - if (pageExists) { - _allPagedResults[currentRequestIndex] = posts; - } - // #10: If the page doesn't exist add the page data - else { - _allPagedResults.add(posts); - } - - // #11: Concatenate the full list to be shown - var allPosts = _allPagedResults.fold>(List(), - (initialValue, pageItems) => initialValue..addAll(pageItems)); - - // #12: Broadcase all posts - _postsController.add(allPosts); - - // #13: Save the last document from the results only if it's the current last page - if (currentRequestIndex == _allPagedResults.length - 1) { - _lastDocument = postsSnapshot.documents.last; - } - - // #14: Determine if there's more posts to request - _hasMorePosts = posts.length == PostsLimit; - } - }); - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - void requestMoreData() => _requestPosts(); -} diff --git a/045-paginated-realtime-firestore/lib/services/navigation_service.dart b/045-paginated-realtime-firestore/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/045-paginated-realtime-firestore/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/045-paginated-realtime-firestore/lib/services/push_notification_service.dart b/045-paginated-realtime-firestore/lib/services/push_notification_service.dart deleted file mode 100644 index a7bf9276..00000000 --- a/045-paginated-realtime-firestore/lib/services/push_notification_service.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:io'; - -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; - -class PushNotificationService { - final FirebaseMessaging _fcm = FirebaseMessaging(); - final NavigationService _navigationService = locator(); - - Future initialise() async { - if (Platform.isIOS) { - // request permissions if we're on android - _fcm.requestNotificationPermissions(IosNotificationSettings()); - } - - _fcm.configure( - // Called when the app is in the foreground and we receive a push notification - onMessage: (Map message) async { - print('onMessage: $message'); - }, - // Called when the app has been closed comlpetely and it's opened - // from the push notification. - onLaunch: (Map message) async { - print('onLaunch: $message'); - _serialiseAndNavigate(message); - }, - // Called when the app is in the background and it's opened - // from the push notification. - onResume: (Map message) async { - print('onResume: $message'); - _serialiseAndNavigate(message); - }, - ); - } - - void _serialiseAndNavigate(Map message) { - var notificationData = message['data']; - var view = notificationData['view']; - - if (view != null) { - // Navigate to the create post view - if (view == 'create_post') { - _navigationService.navigateTo(CreatePostViewRoute); - } - } - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/router.dart b/045-paginated-realtime-firestore/lib/ui/router.dart deleted file mode 100644 index 059f9e7c..00000000 --- a/045-paginated-realtime-firestore/lib/ui/router.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - var postToEdit = settings.arguments as Post; - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/045-paginated-realtime-firestore/lib/ui/shared/app_colors.dart b/045-paginated-realtime-firestore/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/045-paginated-realtime-firestore/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/045-paginated-realtime-firestore/lib/ui/shared/shared_styles.dart b/045-paginated-realtime-firestore/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/045-paginated-realtime-firestore/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/045-paginated-realtime-firestore/lib/ui/shared/ui_helpers.dart b/045-paginated-realtime-firestore/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/045-paginated-realtime-firestore/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/045-paginated-realtime-firestore/lib/ui/views/create_post_view.dart b/045-paginated-realtime-firestore/lib/ui/views/create_post_view.dart deleted file mode 100644 index bc0d5d0b..00000000 --- a/045-paginated-realtime-firestore/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,80 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - CreatePostView({Key key, this.edittingPost}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - GestureDetector( - // When we tap we call selectImage - onTap: () => model.selectImage(), - child: Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - // If the selected image is null we show "Tap to add post image" - child: model.selectedImage == null - ? Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ) - // If we have a selected image we want to show it - : Image.file(model.selectedImage), - ), - ) - ], - ), - )), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/views/home_view.dart b/045-paginated-realtime-firestore/lib/ui/views/home_view.dart deleted file mode 100644 index 5e42665a..00000000 --- a/045-paginated-realtime-firestore/lib/ui/views/home_view.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/creation_aware_list_item.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: !model.busy - ? Icon(Icons.add) - : Center(child: CircularProgressIndicator()), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - CreationAwareListItem( - itemCreated: () { - if (index % 20 == 0) - model.requestMoreData(); - }, - child: GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => - model.deletePost(index), - ), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/views/login_view.dart b/045-paginated-realtime-firestore/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/045-paginated-realtime-firestore/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/views/signup_view.dart b/045-paginated-realtime-firestore/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/045-paginated-realtime-firestore/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/views/startup_view.dart b/045-paginated-realtime-firestore/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/045-paginated-realtime-firestore/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/busy_button.dart b/045-paginated-realtime-firestore/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/busy_overlay.dart b/045-paginated-realtime-firestore/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/creation_aware_list_item.dart b/045-paginated-realtime-firestore/lib/ui/widgets/creation_aware_list_item.dart deleted file mode 100644 index 07739f9c..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/creation_aware_list_item.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -class CreationAwareListItem extends StatefulWidget { - final Function itemCreated; - final Widget child; - const CreationAwareListItem({ - Key key, - this.itemCreated, - this.child, - }) : super(key: key); - - @override - _CreationAwareListItemState createState() => _CreationAwareListItemState(); -} - -class _CreationAwareListItemState extends State { - @override - void initState() { - super.initState(); - if (widget.itemCreated != null) { - widget.itemCreated(); - } - } - - @override - Widget build(BuildContext context) { - return widget.child; - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/expansion_list.dart b/045-paginated-realtime-firestore/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/input_field.dart b/045-paginated-realtime-firestore/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/note_text.dart b/045-paginated-realtime-firestore/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/post_item.dart b/045-paginated-realtime-firestore/lib/ui/widgets/post_item.dart deleted file mode 100644 index f8580fac..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: post.imageUrl != null ? null : 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // If the image is not null load the imageURL - post.imageUrl != null - ? SizedBox( - height: 250, - child: CachedNetworkImage( - imageUrl: post.imageUrl, - placeholder: (context, url) => - CircularProgressIndicator(), - errorWidget: (context, url, error) => - Icon(Icons.error), - ), - ) - // If the image is null show nothing - : Container(), - Text(post.title), - ], - ), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/ui/widgets/text_link.dart b/045-paginated-realtime-firestore/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/045-paginated-realtime-firestore/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/045-paginated-realtime-firestore/lib/utils/image_selector.dart b/045-paginated-realtime-firestore/lib/utils/image_selector.dart deleted file mode 100644 index df91fc25..00000000 --- a/045-paginated-realtime-firestore/lib/utils/image_selector.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -class ImageSelector { - Future selectImage() async { - return await ImagePicker().getImage(source: ImageSource.gallery); - } -} diff --git a/045-paginated-realtime-firestore/lib/viewmodels/base_model.dart b/045-paginated-realtime-firestore/lib/viewmodels/base_model.dart deleted file mode 100644 index ac8f755b..00000000 --- a/045-paginated-realtime-firestore/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/045-paginated-realtime-firestore/lib/viewmodels/create_post_view_model.dart b/045-paginated-realtime-firestore/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index f84026f0..00000000 --- a/045-paginated-realtime-firestore/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:io'; - -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final ImageSelector _imageSelector = locator(); - final CloudStorageService _cloudStorageService = - locator(); - final AnalyticsService _analyticsService = locator(); - - File _selectedImage; - File get selectedImage => _selectedImage; - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future selectImage() async { - var tempImage = await _imageSelector.selectImage(); - if (tempImage != null) { - _selectedImage = File(tempImage.path); - notifyListeners(); - } - } - - Future addPost({@required String title}) async { - setBusy(true); - - CloudStorageResult storageResult; - - if (!_editting) { - storageResult = await _cloudStorageService.uploadImage( - imageToUpload: _selectedImage, - title: title, - ); - } - - var result; - - if (!_editting) { - result = await _firestoreService.addPost(Post( - title: title, - userId: currentUser.id, - imageUrl: storageResult.imageUrl, - imageFileName: storageResult.imageFileName, - )); - - await _analyticsService.logPostCreated(hasImage: _selectedImage != null); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - imageUrl: _edittingPost.imageUrl, - imageFileName: _edittingPost.imageFileName, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/045-paginated-realtime-firestore/lib/viewmodels/home_view_model.dart b/045-paginated-realtime-firestore/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 9d3fa639..00000000 --- a/045-paginated-realtime-firestore/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - var postToDelete = _posts[index]; - setBusy(true); - await _firestoreService.deletePost(postToDelete.documentId); - // Delete the image after the post is deleted - await _cloudStorageService.deleteImage(postToDelete.imageFileName); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } - - void requestMoreData() => _firestoreService.requestMoreData(); -} diff --git a/045-paginated-realtime-firestore/lib/viewmodels/login_view_model.dart b/045-paginated-realtime-firestore/lib/viewmodels/login_view_model.dart deleted file mode 100644 index a557a91a..00000000 --- a/045-paginated-realtime-firestore/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logLogin(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/045-paginated-realtime-firestore/lib/viewmodels/signup_view_model.dart b/045-paginated-realtime-firestore/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index b23ed4d2..00000000 --- a/045-paginated-realtime-firestore/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logSignUp(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/045-paginated-realtime-firestore/lib/viewmodels/startup_view_model.dart b/045-paginated-realtime-firestore/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index 36d387fb..00000000 --- a/045-paginated-realtime-firestore/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - final PushNotificationService _pushNotificationService = - locator(); - - Future handleStartUpLogic() async { - // Register for push notifications - await _pushNotificationService.initialise(); - - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/045-paginated-realtime-firestore/pubspec.lock b/045-paginated-realtime-firestore/pubspec.lock deleted file mode 100644 index 53ef17ac..00000000 --- a/045-paginated-realtime-firestore/pubspec.lock +++ /dev/null @@ -1,607 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.10" - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.3" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "5.9.1" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - cross_file: - dependency: transitive - description: - name: cross_file - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.3+2" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.4" - firebase_analytics: - dependency: "direct main" - description: - name: firebase_analytics - url: "https://pub.dartlang.org" - source: hosted - version: "5.0.15" - firebase_analytics_platform_interface: - dependency: transitive - description: - name: firebase_analytics_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "6.11.4" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.5.2" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - url: "https://pub.dartlang.org" - source: hosted - version: "14.1.4" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.8" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.9" - firebase_storage: - dependency: "direct main" - description: - name: firebase_storage - url: "https://pub.dartlang.org" - source: hosted - version: "11.0.7" - firebase_storage_platform_interface: - dependency: transitive - description: - name: firebase_storage_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.25" - firebase_storage_web: - dependency: transitive - description: - name: firebase_storage_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.17" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.7" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - image_picker: - dependency: "direct main" - description: - name: image_picker - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6" - image_picker_android: - dependency: transitive - description: - name: image_picker_android - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.5+3" - image_picker_for_web: - dependency: transitive - description: - name: image_picker_for_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.10" - image_picker_ios: - dependency: transitive - description: - name: image_picker_ios - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6+1" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.6.2" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.17.0" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - octo_image: - dependency: transitive - description: - name: octo_image - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.22" - path_provider_ios: - dependency: transitive - description: - name: path_provider_ios - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.6" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.1" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.27.7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - sqflite: - dependency: transitive - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0+2" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0+3" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.2" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" -sdks: - dart: ">=2.18.0 <3.0.0" - flutter: ">=3.3.0" diff --git a/045-paginated-realtime-firestore/pubspec.yaml b/045-paginated-realtime-firestore/pubspec.yaml deleted file mode 100644 index 05f2a189..00000000 --- a/045-paginated-realtime-firestore/pubspec.yaml +++ /dev/null @@ -1,88 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ">=0.12.1 <0.14.0" - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ">=0.16.1 <5.0.0" - cloud_firestore: ">=0.13.6 <5.0.0" - firebase_storage: ">=3.1.6 <12.0.0" - image_picker: ">=0.6.7+2 <0.9.0" - cached_network_image: ">=2.2.0+1 <4.0.0" - firebase_messaging: ">=6.0.16 <15.0.0" - firebase_analytics: ^5.0.15 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/046-dynamic-links/.flutter-plugins-dependencies b/046-dynamic-links/.flutter-plugins-dependencies deleted file mode 100644 index 78324424..00000000 --- a/046-dynamic-links/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_dynamic_links","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_dynamic_links-0.5.1/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":[]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_dynamic_links","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_dynamic_links-0.5.1/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.5/","dependencies":[]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_analytics","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_dynamic_links","dependencies":[]},{"name":"firebase_messaging","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:48:45.149162","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/046-dynamic-links/.gitignore b/046-dynamic-links/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/046-dynamic-links/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/046-dynamic-links/.metadata b/046-dynamic-links/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/046-dynamic-links/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/046-dynamic-links/README.md b/046-dynamic-links/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/046-dynamic-links/assets/fonts/OpenSans-Bold.ttf b/046-dynamic-links/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/046-dynamic-links/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/046-dynamic-links/assets/fonts/OpenSans-ExtraBold.ttf b/046-dynamic-links/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/046-dynamic-links/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/046-dynamic-links/assets/fonts/OpenSans-Light.ttf b/046-dynamic-links/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/046-dynamic-links/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/046-dynamic-links/assets/fonts/OpenSans-Regular.ttf b/046-dynamic-links/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/046-dynamic-links/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/046-dynamic-links/assets/images/icon_large.png b/046-dynamic-links/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/046-dynamic-links/assets/images/icon_large.png and /dev/null differ diff --git a/046-dynamic-links/assets/images/title.png b/046-dynamic-links/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/046-dynamic-links/assets/images/title.png and /dev/null differ diff --git a/046-dynamic-links/lib/constants/route_names.dart b/046-dynamic-links/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/046-dynamic-links/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/046-dynamic-links/lib/locator.dart b/046-dynamic-links/lib/locator.dart deleted file mode 100644 index 6d4724f6..00000000 --- a/046-dynamic-links/lib/locator.dart +++ /dev/null @@ -1,24 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dynamic_link_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); - locator.registerLazySingleton(() => CloudStorageService()); - locator.registerLazySingleton(() => ImageSelector()); - locator.registerLazySingleton(() => PushNotificationService()); - locator.registerLazySingleton(() => AnalyticsService()); - locator.registerLazySingleton(() => DynamicLinkService()); -} diff --git a/046-dynamic-links/lib/main.dart b/046-dynamic-links/lib/main.dart deleted file mode 100644 index ed8c71c1..00000000 --- a/046-dynamic-links/lib/main.dart +++ /dev/null @@ -1,39 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -void main() { - // Register all the models and services before the app starts - setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - navigatorObservers: [locator().getAnalyticsObserver()], - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/046-dynamic-links/lib/managers/dialog_manager.dart b/046-dynamic-links/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/046-dynamic-links/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/046-dynamic-links/lib/models/dialog_models.dart b/046-dynamic-links/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/046-dynamic-links/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/046-dynamic-links/lib/models/post.dart b/046-dynamic-links/lib/models/post.dart deleted file mode 100644 index 36ad43a5..00000000 --- a/046-dynamic-links/lib/models/post.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - final String imageFileName; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - this.imageFileName, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - 'imageFileName': imageFileName, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - imageFileName: map['imageFileName'], - documentId: documentId, - ); - } -} diff --git a/046-dynamic-links/lib/models/user.dart b/046-dynamic-links/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/046-dynamic-links/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/046-dynamic-links/lib/services/analytics_service.dart b/046-dynamic-links/lib/services/analytics_service.dart deleted file mode 100644 index 7139155b..00000000 --- a/046-dynamic-links/lib/services/analytics_service.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:firebase_analytics/firebase_analytics.dart'; -import 'package:firebase_analytics/observer.dart'; -import 'package:flutter/foundation.dart'; - -class AnalyticsService { - final FirebaseAnalytics _analytics = FirebaseAnalytics(); - - FirebaseAnalyticsObserver getAnalyticsObserver() => - FirebaseAnalyticsObserver(analytics: _analytics); - - // User properties tells us what the user is - Future setUserProperties({@required String userId, String userRole}) async { - await _analytics.setUserId(userId); - await _analytics.setUserProperty(name: 'user_role', value: userRole); - // property to indicate if it's a pro paying member - // property that might tell us it's a regular poster, etc - } - - Future logLogin() async { - await _analytics.logLogin(loginMethod: 'email'); - } - - Future logSignUp() async { - await _analytics.logSignUp(signUpMethod: 'email'); - } - - Future logPostCreated({bool hasImage}) async { - await _analytics.logEvent( - name: 'create_post', - parameters: {'has_image': hasImage}, - ); - } -} diff --git a/046-dynamic-links/lib/services/authentication_service.dart b/046-dynamic-links/lib/services/authentication_service.dart deleted file mode 100644 index 130d74a6..00000000 --- a/046-dynamic-links/lib/services/authentication_service.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - final AnalyticsService _analyticsService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - await _analyticsService.setUserProperties( - userId: authResult.user.uid, - userRole: _currentUser.userRole, - ); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - await _analyticsService.setUserProperties( - userId: user.uid, - userRole: _currentUser.userRole, - ); - } - } -} diff --git a/046-dynamic-links/lib/services/cloud_storage_service.dart b/046-dynamic-links/lib/services/cloud_storage_service.dart deleted file mode 100644 index fad3c58b..00000000 --- a/046-dynamic-links/lib/services/cloud_storage_service.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; - -import 'package:firebase_storage/firebase_storage.dart'; -import 'package:flutter/foundation.dart'; - -class CloudStorageService { - Future uploadImage({ - @required File imageToUpload, - @required String title, - }) async { - var imageFileName = - title + DateTime.now().millisecondsSinceEpoch.toString(); - - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - StorageUploadTask uploadTask = firebaseStorageRef.putFile(imageToUpload); - - StorageTaskSnapshot storageSnapshot = await uploadTask.onComplete; - - var downloadUrl = await storageSnapshot.ref.getDownloadURL(); - - if (uploadTask.isComplete) { - var url = downloadUrl.toString(); - return CloudStorageResult( - imageUrl: url, - imageFileName: imageFileName, - ); - } - - return null; - } - - Future deleteImage(String imageFileName) async { - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - try { - await firebaseStorageRef.delete(); - return true; - } catch (e) { - return e.toString(); - } - } -} - -class CloudStorageResult { - final String imageUrl; - final String imageFileName; - - CloudStorageResult({this.imageUrl, this.imageFileName}); -} diff --git a/046-dynamic-links/lib/services/dialog_service.dart b/046-dynamic-links/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/046-dynamic-links/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/046-dynamic-links/lib/services/dynamic_link_service.dart b/046-dynamic-links/lib/services/dynamic_link_service.dart deleted file mode 100644 index 3c4ac7db..00000000 --- a/046-dynamic-links/lib/services/dynamic_link_service.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; - -class DynamicLinkService { - final NavigationService _navigationService = locator(); - - Future handleDynamicLinks() async { - // Get the initial dynamic link if the app is opened with a dynamic link - final PendingDynamicLinkData data = - await FirebaseDynamicLinks.instance.getInitialLink(); - - // handle link that has been retrieved - _handleDeepLink(data); - - // Register a link callback to fire if the app is opened up from the background - // using a dynamic link. - FirebaseDynamicLinks.instance.onLink( - onSuccess: (PendingDynamicLinkData dynamicLink) async { - // handle link that has been retrieved - _handleDeepLink(dynamicLink); - }, onError: (OnLinkErrorException e) async { - print('Link Failed: ${e.message}'); - }); - } - - void _handleDeepLink(PendingDynamicLinkData data) { - final Uri deepLink = data?.link; - if (deepLink != null) { - print('_handleDeepLink | deeplink: $deepLink'); - - var isPost = deepLink.pathSegments.contains('post'); - if (isPost) { - var title = deepLink.queryParameters['title']; - if (title != null) { - _navigationService.navigateTo(CreatePostViewRoute, arguments: title); - } - } - } - } - - Future createFirstPostLink(String title) async { - final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://filledstacks.page.link', - link: Uri.parse('https://www.compound.com/post?title=$title'), - androidParameters: AndroidParameters( - packageName: 'com.filledstacks.compound', - ), - - - - - // Other things to add as an example. We don't need it now - iosParameters: IosParameters( - bundleId: 'com.example.ios', - minimumVersion: '1.0.1', - appStoreId: '123456789', - ), - googleAnalyticsParameters: GoogleAnalyticsParameters( - campaign: 'example-promo', - medium: 'social', - source: 'orkut', - ), - itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( - providerToken: '123456', - campaignToken: 'example-promo', - ), - socialMetaTagParameters: SocialMetaTagParameters( - title: 'Example of a Dynamic Link', - description: 'This link works whether app is installed or not!', - ), - ); - - final Uri dynamicUrl = await parameters.buildUrl(); - - return dynamicUrl.toString(); - } -} diff --git a/046-dynamic-links/lib/services/firestore_service.dart b/046-dynamic-links/lib/services/firestore_service.dart deleted file mode 100644 index 7f845889..00000000 --- a/046-dynamic-links/lib/services/firestore_service.dart +++ /dev/null @@ -1,166 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - // #6: Create a list that will keep the paged results - List> _allPagedResults = List>(); - - static const int PostsLimit = 20; - - DocumentSnapshot _lastDocument; - bool _hasMorePosts = true; - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = - await _postsCollectionReference.limit(PostsLimit).getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _requestPosts(); - return _postsController.stream; - } - - // #1: Move the request posts into it's own function - void _requestPosts() { - // #2: split the query from the actual subscription - var pagePostsQuery = _postsCollectionReference - .orderBy('title') - // #3: Limit the amount of results - .limit(PostsLimit); - - // #5: If we have a document start the query after it - if (_lastDocument != null) { - pagePostsQuery = pagePostsQuery.startAfterDocument(_lastDocument); - } - - if (!_hasMorePosts) return; - - // #7: Get and store the page index that the results belong to - var currentRequestIndex = _allPagedResults.length; - - pagePostsQuery.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // #8: Check if the page exists or not - var pageExists = currentRequestIndex < _allPagedResults.length; - - // #9: If the page exists update the posts for that page - if (pageExists) { - _allPagedResults[currentRequestIndex] = posts; - } - // #10: If the page doesn't exist add the page data - else { - _allPagedResults.add(posts); - } - - // #11: Concatenate the full list to be shown - var allPosts = _allPagedResults.fold>(List(), - (initialValue, pageItems) => initialValue..addAll(pageItems)); - - // #12: Broadcase all posts - _postsController.add(allPosts); - - // #13: Save the last document from the results only if it's the current last page - if (currentRequestIndex == _allPagedResults.length - 1) { - _lastDocument = postsSnapshot.documents.last; - } - - // #14: Determine if there's more posts to request - _hasMorePosts = posts.length == PostsLimit; - } - }); - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - void requestMoreData() => _requestPosts(); -} diff --git a/046-dynamic-links/lib/services/navigation_service.dart b/046-dynamic-links/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/046-dynamic-links/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/046-dynamic-links/lib/services/push_notification_service.dart b/046-dynamic-links/lib/services/push_notification_service.dart deleted file mode 100644 index a7bf9276..00000000 --- a/046-dynamic-links/lib/services/push_notification_service.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:io'; - -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; - -class PushNotificationService { - final FirebaseMessaging _fcm = FirebaseMessaging(); - final NavigationService _navigationService = locator(); - - Future initialise() async { - if (Platform.isIOS) { - // request permissions if we're on android - _fcm.requestNotificationPermissions(IosNotificationSettings()); - } - - _fcm.configure( - // Called when the app is in the foreground and we receive a push notification - onMessage: (Map message) async { - print('onMessage: $message'); - }, - // Called when the app has been closed comlpetely and it's opened - // from the push notification. - onLaunch: (Map message) async { - print('onLaunch: $message'); - _serialiseAndNavigate(message); - }, - // Called when the app is in the background and it's opened - // from the push notification. - onResume: (Map message) async { - print('onResume: $message'); - _serialiseAndNavigate(message); - }, - ); - } - - void _serialiseAndNavigate(Map message) { - var notificationData = message['data']; - var view = notificationData['view']; - - if (view != null) { - // Navigate to the create post view - if (view == 'create_post') { - _navigationService.navigateTo(CreatePostViewRoute); - } - } - } -} diff --git a/046-dynamic-links/lib/ui/router.dart b/046-dynamic-links/lib/ui/router.dart deleted file mode 100644 index b09bc49f..00000000 --- a/046-dynamic-links/lib/ui/router.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - String postTitle; - Post postToEdit; - if (settings.arguments is String) { - postTitle = settings.arguments; - } else if (settings.arguments is Post) { - postToEdit = settings.arguments as Post; - } - - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - postTitle: postTitle, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/046-dynamic-links/lib/ui/shared/app_colors.dart b/046-dynamic-links/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/046-dynamic-links/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/046-dynamic-links/lib/ui/shared/shared_styles.dart b/046-dynamic-links/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/046-dynamic-links/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/046-dynamic-links/lib/ui/shared/ui_helpers.dart b/046-dynamic-links/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/046-dynamic-links/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/046-dynamic-links/lib/ui/views/create_post_view.dart b/046-dynamic-links/lib/ui/views/create_post_view.dart deleted file mode 100644 index d1255927..00000000 --- a/046-dynamic-links/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - final String postTitle; - CreatePostView({ - Key key, - this.edittingPost, - this.postTitle, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - if (edittingPost != null) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - } else if (postTitle != null) { - titleController.text = postTitle; - } - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - GestureDetector( - // When we tap we call selectImage - onTap: () => model.selectImage(), - child: Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - // If the selected image is null we show "Tap to add post image" - child: model.selectedImage == null - ? Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ) - // If we have a selected image we want to show it - : Image.file(model.selectedImage), - ), - ) - ], - ), - )), - ); - } -} diff --git a/046-dynamic-links/lib/ui/views/home_view.dart b/046-dynamic-links/lib/ui/views/home_view.dart deleted file mode 100644 index 5e42665a..00000000 --- a/046-dynamic-links/lib/ui/views/home_view.dart +++ /dev/null @@ -1,71 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/creation_aware_list_item.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: !model.busy - ? Icon(Icons.add) - : Center(child: CircularProgressIndicator()), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - CreationAwareListItem( - itemCreated: () { - if (index % 20 == 0) - model.requestMoreData(); - }, - child: GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => - model.deletePost(index), - ), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/046-dynamic-links/lib/ui/views/login_view.dart b/046-dynamic-links/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/046-dynamic-links/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/046-dynamic-links/lib/ui/views/signup_view.dart b/046-dynamic-links/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/046-dynamic-links/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/046-dynamic-links/lib/ui/views/startup_view.dart b/046-dynamic-links/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/046-dynamic-links/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/046-dynamic-links/lib/ui/widgets/busy_button.dart b/046-dynamic-links/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/046-dynamic-links/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/046-dynamic-links/lib/ui/widgets/busy_overlay.dart b/046-dynamic-links/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/046-dynamic-links/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/046-dynamic-links/lib/ui/widgets/creation_aware_list_item.dart b/046-dynamic-links/lib/ui/widgets/creation_aware_list_item.dart deleted file mode 100644 index 07739f9c..00000000 --- a/046-dynamic-links/lib/ui/widgets/creation_aware_list_item.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -class CreationAwareListItem extends StatefulWidget { - final Function itemCreated; - final Widget child; - const CreationAwareListItem({ - Key key, - this.itemCreated, - this.child, - }) : super(key: key); - - @override - _CreationAwareListItemState createState() => _CreationAwareListItemState(); -} - -class _CreationAwareListItemState extends State { - @override - void initState() { - super.initState(); - if (widget.itemCreated != null) { - widget.itemCreated(); - } - } - - @override - Widget build(BuildContext context) { - return widget.child; - } -} diff --git a/046-dynamic-links/lib/ui/widgets/expansion_list.dart b/046-dynamic-links/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/046-dynamic-links/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/046-dynamic-links/lib/ui/widgets/input_field.dart b/046-dynamic-links/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/046-dynamic-links/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/046-dynamic-links/lib/ui/widgets/note_text.dart b/046-dynamic-links/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/046-dynamic-links/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/046-dynamic-links/lib/ui/widgets/post_item.dart b/046-dynamic-links/lib/ui/widgets/post_item.dart deleted file mode 100644 index f8580fac..00000000 --- a/046-dynamic-links/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: post.imageUrl != null ? null : 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // If the image is not null load the imageURL - post.imageUrl != null - ? SizedBox( - height: 250, - child: CachedNetworkImage( - imageUrl: post.imageUrl, - placeholder: (context, url) => - CircularProgressIndicator(), - errorWidget: (context, url, error) => - Icon(Icons.error), - ), - ) - // If the image is null show nothing - : Container(), - Text(post.title), - ], - ), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/046-dynamic-links/lib/ui/widgets/text_link.dart b/046-dynamic-links/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/046-dynamic-links/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/046-dynamic-links/lib/utils/image_selector.dart b/046-dynamic-links/lib/utils/image_selector.dart deleted file mode 100644 index df91fc25..00000000 --- a/046-dynamic-links/lib/utils/image_selector.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -class ImageSelector { - Future selectImage() async { - return await ImagePicker().getImage(source: ImageSource.gallery); - } -} diff --git a/046-dynamic-links/lib/viewmodels/base_model.dart b/046-dynamic-links/lib/viewmodels/base_model.dart deleted file mode 100644 index ac8f755b..00000000 --- a/046-dynamic-links/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,19 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/046-dynamic-links/lib/viewmodels/create_post_view_model.dart b/046-dynamic-links/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index f84026f0..00000000 --- a/046-dynamic-links/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:io'; - -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final ImageSelector _imageSelector = locator(); - final CloudStorageService _cloudStorageService = - locator(); - final AnalyticsService _analyticsService = locator(); - - File _selectedImage; - File get selectedImage => _selectedImage; - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future selectImage() async { - var tempImage = await _imageSelector.selectImage(); - if (tempImage != null) { - _selectedImage = File(tempImage.path); - notifyListeners(); - } - } - - Future addPost({@required String title}) async { - setBusy(true); - - CloudStorageResult storageResult; - - if (!_editting) { - storageResult = await _cloudStorageService.uploadImage( - imageToUpload: _selectedImage, - title: title, - ); - } - - var result; - - if (!_editting) { - result = await _firestoreService.addPost(Post( - title: title, - userId: currentUser.id, - imageUrl: storageResult.imageUrl, - imageFileName: storageResult.imageFileName, - )); - - await _analyticsService.logPostCreated(hasImage: _selectedImage != null); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - imageUrl: _edittingPost.imageUrl, - imageFileName: _edittingPost.imageFileName, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/046-dynamic-links/lib/viewmodels/home_view_model.dart b/046-dynamic-links/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 9d3fa639..00000000 --- a/046-dynamic-links/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - var postToDelete = _posts[index]; - setBusy(true); - await _firestoreService.deletePost(postToDelete.documentId); - // Delete the image after the post is deleted - await _cloudStorageService.deleteImage(postToDelete.imageFileName); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } - - void requestMoreData() => _firestoreService.requestMoreData(); -} diff --git a/046-dynamic-links/lib/viewmodels/login_view_model.dart b/046-dynamic-links/lib/viewmodels/login_view_model.dart deleted file mode 100644 index a557a91a..00000000 --- a/046-dynamic-links/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logLogin(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/046-dynamic-links/lib/viewmodels/signup_view_model.dart b/046-dynamic-links/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index b23ed4d2..00000000 --- a/046-dynamic-links/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logSignUp(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/046-dynamic-links/lib/viewmodels/startup_view_model.dart b/046-dynamic-links/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index c0724c6e..00000000 --- a/046-dynamic-links/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dynamic_link_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - final PushNotificationService _pushNotificationService = - locator(); - final DynamicLinkService _dynamicLinkService = locator(); - - Future handleStartUpLogic() async { - await _dynamicLinkService.handleDynamicLinks(); - - // Register for push notifications - await _pushNotificationService.initialise(); - - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/046-dynamic-links/pubspec.lock b/046-dynamic-links/pubspec.lock deleted file mode 100644 index 8b75b711..00000000 --- a/046-dynamic-links/pubspec.lock +++ /dev/null @@ -1,614 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.10" - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.3" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "5.9.1" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - cross_file: - dependency: transitive - description: - name: cross_file - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.3+2" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.4" - firebase_analytics: - dependency: "direct main" - description: - name: firebase_analytics - url: "https://pub.dartlang.org" - source: hosted - version: "5.0.15" - firebase_analytics_platform_interface: - dependency: transitive - description: - name: firebase_analytics_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "6.11.4" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.5.2" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - firebase_dynamic_links: - dependency: "direct main" - description: - name: firebase_dynamic_links - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.1" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - url: "https://pub.dartlang.org" - source: hosted - version: "14.1.4" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.8" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.9" - firebase_storage: - dependency: "direct main" - description: - name: firebase_storage - url: "https://pub.dartlang.org" - source: hosted - version: "11.0.7" - firebase_storage_platform_interface: - dependency: transitive - description: - name: firebase_storage_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.25" - firebase_storage_web: - dependency: transitive - description: - name: firebase_storage_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.17" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.7" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - image_picker: - dependency: "direct main" - description: - name: image_picker - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6" - image_picker_android: - dependency: transitive - description: - name: image_picker_android - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.5+3" - image_picker_for_web: - dependency: transitive - description: - name: image_picker_for_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.10" - image_picker_ios: - dependency: transitive - description: - name: image_picker_ios - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6+1" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.6.2" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.17.0" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - octo_image: - dependency: transitive - description: - name: octo_image - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.22" - path_provider_ios: - dependency: transitive - description: - name: path_provider_ios - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.6" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.1" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.27.7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - sqflite: - dependency: transitive - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0+2" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0+3" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.2" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" -sdks: - dart: ">=2.18.0 <3.0.0" - flutter: ">=3.3.0" diff --git a/046-dynamic-links/pubspec.yaml b/046-dynamic-links/pubspec.yaml deleted file mode 100644 index 9297081e..00000000 --- a/046-dynamic-links/pubspec.yaml +++ /dev/null @@ -1,89 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ">=0.12.1 <0.14.0" - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ">=0.16.1 <5.0.0" - cloud_firestore: ">=0.13.6 <5.0.0" - firebase_storage: ">=3.1.6 <12.0.0" - image_picker: ">=0.6.7+2 <0.9.0" - cached_network_image: ">=2.2.0+1 <4.0.0" - firebase_messaging: ">=6.0.16 <15.0.0" - firebase_analytics: ^5.0.15 - firebase_dynamic_links: ^0.5.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/047-remote-config/.flutter-plugins-dependencies b/047-remote-config/.flutter-plugins-dependencies deleted file mode 100644 index 709d3002..00000000 --- a/047-remote-config/.flutter-plugins-dependencies +++ /dev/null @@ -1 +0,0 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_dynamic_links","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_dynamic_links-0.5.1/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_remote_config","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_remote_config-0.3.1/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":[]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"android":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_analytics","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_analytics-5.0.15/","dependencies":[]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_dynamic_links","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_dynamic_links-0.5.1/","dependencies":[]},{"name":"firebase_messaging","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_messaging-6.0.16/","dependencies":[]},{"name":"firebase_remote_config","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_remote_config-0.3.1/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/flutter_plugin_android_lifecycle-1.0.5/","dependencies":[]},{"name":"image_picker","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/image_picker-0.6.7+2/","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.0/","dependencies":[]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"macos":[{"name":"cloud_firestore","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore-0.13.6/","dependencies":["firebase_core"]},{"name":"firebase_auth","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth-0.16.1/","dependencies":["firebase_core"]},{"name":"firebase_core","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core-0.4.5/","dependencies":[]},{"name":"firebase_storage","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_storage-3.1.6/","dependencies":["firebase_core"]},{"name":"sqflite","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/sqflite-1.2.0/","dependencies":[]}],"linux":[],"windows":[],"web":[{"name":"cloud_firestore_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/cloud_firestore_web-0.1.1+2/","dependencies":[]},{"name":"firebase_auth_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_auth_web-0.1.1+2/","dependencies":[]},{"name":"firebase_core_web","path":"/Users/brandonsneider/.pub-cache/hosted/pub.dartlang.org/firebase_core_web-0.1.1+2/","dependencies":[]}]},"dependencyGraph":[{"name":"cloud_firestore","dependencies":["firebase_core","cloud_firestore_web"]},{"name":"cloud_firestore_web","dependencies":["firebase_core"]},{"name":"firebase_analytics","dependencies":[]},{"name":"firebase_auth","dependencies":["firebase_core","firebase_auth_web"]},{"name":"firebase_auth_web","dependencies":[]},{"name":"firebase_core","dependencies":["firebase_core_web"]},{"name":"firebase_core_web","dependencies":[]},{"name":"firebase_dynamic_links","dependencies":[]},{"name":"firebase_messaging","dependencies":[]},{"name":"firebase_remote_config","dependencies":[]},{"name":"firebase_storage","dependencies":["firebase_core"]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"image_picker","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"path_provider","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-06-18 21:48:41.897914","version":"1.20.0-0.0.pre"} \ No newline at end of file diff --git a/047-remote-config/.gitignore b/047-remote-config/.gitignore deleted file mode 100644 index 5be59a14..00000000 --- a/047-remote-config/.gitignore +++ /dev/null @@ -1,70 +0,0 @@ -# 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/ -.dart_tool/ -.flutter-plugins -.packages -.pub-cache/ -.pub/ -/build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/047-remote-config/.metadata b/047-remote-config/.metadata deleted file mode 100644 index 0012359c..00000000 --- a/047-remote-config/.metadata +++ /dev/null @@ -1,10 +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: 740fb2a8bb6d43a475ce76f7fe3e5fc10bbe24ff - channel: master - -project_type: app diff --git a/047-remote-config/README.md b/047-remote-config/README.md deleted file mode 100644 index e69de29b..00000000 diff --git a/047-remote-config/assets/fonts/OpenSans-Bold.ttf b/047-remote-config/assets/fonts/OpenSans-Bold.ttf deleted file mode 100644 index 7b529456..00000000 Binary files a/047-remote-config/assets/fonts/OpenSans-Bold.ttf and /dev/null differ diff --git a/047-remote-config/assets/fonts/OpenSans-ExtraBold.ttf b/047-remote-config/assets/fonts/OpenSans-ExtraBold.ttf deleted file mode 100644 index 3660681d..00000000 Binary files a/047-remote-config/assets/fonts/OpenSans-ExtraBold.ttf and /dev/null differ diff --git a/047-remote-config/assets/fonts/OpenSans-Light.ttf b/047-remote-config/assets/fonts/OpenSans-Light.ttf deleted file mode 100644 index 563872c7..00000000 Binary files a/047-remote-config/assets/fonts/OpenSans-Light.ttf and /dev/null differ diff --git a/047-remote-config/assets/fonts/OpenSans-Regular.ttf b/047-remote-config/assets/fonts/OpenSans-Regular.ttf deleted file mode 100644 index 2e31d024..00000000 Binary files a/047-remote-config/assets/fonts/OpenSans-Regular.ttf and /dev/null differ diff --git a/047-remote-config/assets/images/icon_large.png b/047-remote-config/assets/images/icon_large.png deleted file mode 100644 index 506471a1..00000000 Binary files a/047-remote-config/assets/images/icon_large.png and /dev/null differ diff --git a/047-remote-config/assets/images/title.png b/047-remote-config/assets/images/title.png deleted file mode 100644 index 96c4bfee..00000000 Binary files a/047-remote-config/assets/images/title.png and /dev/null differ diff --git a/047-remote-config/lib/constants/route_names.dart b/047-remote-config/lib/constants/route_names.dart deleted file mode 100644 index 3b3a7b99..00000000 --- a/047-remote-config/lib/constants/route_names.dart +++ /dev/null @@ -1,5 +0,0 @@ -const String LoginViewRoute = "LoginView"; -const String SignUpViewRoute = "SignUp"; -const String HomeViewRoute = "HomeView"; -const String CreatePostViewRoute = "CreatePostView"; -// Generate the views here diff --git a/047-remote-config/lib/locator.dart b/047-remote-config/lib/locator.dart deleted file mode 100644 index 6d42027a..00000000 --- a/047-remote-config/lib/locator.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dynamic_link_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/services/remote_config_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:get_it/get_it.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; - -GetIt locator = GetIt.instance; - -Future setupLocator() async { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DialogService()); - locator.registerLazySingleton(() => AuthenticationService()); - locator.registerLazySingleton(() => FirestoreService()); - locator.registerLazySingleton(() => CloudStorageService()); - locator.registerLazySingleton(() => ImageSelector()); - locator.registerLazySingleton(() => PushNotificationService()); - locator.registerLazySingleton(() => AnalyticsService()); - locator.registerLazySingleton(() => DynamicLinkService()); - - var remoteConfigService = await RemoteConfigService.getInstance(); - locator.registerSingleton(remoteConfigService); -} diff --git a/047-remote-config/lib/main.dart b/047-remote-config/lib/main.dart deleted file mode 100644 index aafe2a07..00000000 --- a/047-remote-config/lib/main.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/ui/views/startup_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'managers/dialog_manager.dart'; -import 'ui/router.dart'; -import 'locator.dart'; - -Future main() async { - WidgetsFlutterBinding.ensureInitialized(); - - // Register all the models and services before the app starts - await setupLocator(); - - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Compound', - builder: (context, child) => Navigator( - key: locator().dialogNavigationKey, - onGenerateRoute: (settings) => MaterialPageRoute( - builder: (context) => DialogManager(child: child)), - ), - navigatorKey: locator().navigationKey, - navigatorObservers: [locator().getAnalyticsObserver()], - theme: ThemeData( - primaryColor: Color(0xff19c7c1), - textTheme: Theme.of(context).textTheme.apply( - fontFamily: 'Open Sans', - ), - ), - home: StartUpView(), - onGenerateRoute: generateRoute, - ); - } -} diff --git a/047-remote-config/lib/managers/dialog_manager.dart b/047-remote-config/lib/managers/dialog_manager.dart deleted file mode 100644 index 13b5078a..00000000 --- a/047-remote-config/lib/managers/dialog_manager.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/dialog_models.dart'; -import 'package:compound/services/dialog_service.dart'; - -class DialogManager extends StatefulWidget { - final Widget child; - DialogManager({Key key, this.child}) : super(key: key); - - _DialogManagerState createState() => _DialogManagerState(); -} - -class _DialogManagerState extends State { - DialogService _dialogService = locator(); - - @override - void initState() { - super.initState(); - _dialogService.registerDialogListener(_showDialog); - } - - @override - Widget build(BuildContext context) { - return widget.child; - } - - void _showDialog(DialogRequest request) { - var isConfirmationDialog = request.cancelTitle != null; - showDialog( - context: context, - builder: (context) => AlertDialog( - title: Text(request.title), - content: Text(request.description), - actions: [ - if (isConfirmationDialog) - FlatButton( - child: Text(request.cancelTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: false)); - }, - ), - FlatButton( - child: Text(request.buttonTitle), - onPressed: () { - _dialogService - .dialogComplete(DialogResponse(confirmed: true)); - }, - ), - ], - )); - } -} diff --git a/047-remote-config/lib/models/dialog_models.dart b/047-remote-config/lib/models/dialog_models.dart deleted file mode 100644 index 27aa4adf..00000000 --- a/047-remote-config/lib/models/dialog_models.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DialogRequest { - final String title; - final String description; - final String buttonTitle; - final String cancelTitle; - - DialogRequest( - {@required this.title, - @required this.description, - @required this.buttonTitle, - this.cancelTitle}); -} - -class DialogResponse { - final String fieldOne; - final String fieldTwo; - final bool confirmed; - - DialogResponse({ - this.fieldOne, - this.fieldTwo, - this.confirmed, - }); -} diff --git a/047-remote-config/lib/models/post.dart b/047-remote-config/lib/models/post.dart deleted file mode 100644 index 36ad43a5..00000000 --- a/047-remote-config/lib/models/post.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class Post { - final String title; - final String imageUrl; - final String userId; - final String documentId; - final String imageFileName; - - Post({ - @required this.userId, - @required this.title, - this.documentId, - this.imageUrl, - this.imageFileName, - }); - - Map toMap() { - return { - 'userId': userId, - 'title': title, - 'imageUrl': imageUrl, - 'imageFileName': imageFileName, - }; - } - - static Post fromMap(Map map, String documentId) { - if (map == null) return null; - - return Post( - title: map['title'], - imageUrl: map['imageUrl'], - userId: map['userId'], - imageFileName: map['imageFileName'], - documentId: documentId, - ); - } -} diff --git a/047-remote-config/lib/models/user.dart b/047-remote-config/lib/models/user.dart deleted file mode 100644 index a7fcf107..00000000 --- a/047-remote-config/lib/models/user.dart +++ /dev/null @@ -1,23 +0,0 @@ -class User { - final String id; - final String fullName; - final String email; - final String userRole; - - User({this.id, this.fullName, this.email, this.userRole}); - - User.fromData(Map data) - : id = data['id'], - fullName = data['fullName'], - email = data['email'], - userRole = data['userRole']; - - Map toJson() { - return { - 'id': id, - 'fullName': fullName, - 'email': email, - 'userRole': userRole, - }; - } -} diff --git a/047-remote-config/lib/services/analytics_service.dart b/047-remote-config/lib/services/analytics_service.dart deleted file mode 100644 index 7139155b..00000000 --- a/047-remote-config/lib/services/analytics_service.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:firebase_analytics/firebase_analytics.dart'; -import 'package:firebase_analytics/observer.dart'; -import 'package:flutter/foundation.dart'; - -class AnalyticsService { - final FirebaseAnalytics _analytics = FirebaseAnalytics(); - - FirebaseAnalyticsObserver getAnalyticsObserver() => - FirebaseAnalyticsObserver(analytics: _analytics); - - // User properties tells us what the user is - Future setUserProperties({@required String userId, String userRole}) async { - await _analytics.setUserId(userId); - await _analytics.setUserProperty(name: 'user_role', value: userRole); - // property to indicate if it's a pro paying member - // property that might tell us it's a regular poster, etc - } - - Future logLogin() async { - await _analytics.logLogin(loginMethod: 'email'); - } - - Future logSignUp() async { - await _analytics.logSignUp(signUpMethod: 'email'); - } - - Future logPostCreated({bool hasImage}) async { - await _analytics.logEvent( - name: 'create_post', - parameters: {'has_image': hasImage}, - ); - } -} diff --git a/047-remote-config/lib/services/authentication_service.dart b/047-remote-config/lib/services/authentication_service.dart deleted file mode 100644 index 130d74a6..00000000 --- a/047-remote-config/lib/services/authentication_service.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:firebase_auth/firebase_auth.dart'; -import 'package:flutter/foundation.dart'; -import 'package:compound/services/firestore_service.dart'; - -class AuthenticationService { - final FirebaseAuth _firebaseAuth = FirebaseAuth.instance; - final FirestoreService _firestoreService = locator(); - final AnalyticsService _analyticsService = locator(); - - User _currentUser; - User get currentUser => _currentUser; - - Future loginWithEmail({ - @required String email, - @required String password, - }) async { - try { - var authResult = await _firebaseAuth.signInWithEmailAndPassword( - email: email, - password: password, - ); - await _populateCurrentUser(authResult.user); - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future signUpWithEmail({ - @required String email, - @required String password, - @required String fullName, - @required String role, - }) async { - try { - var authResult = await _firebaseAuth.createUserWithEmailAndPassword( - email: email, - password: password, - ); - - // create a new user profile on firestore - _currentUser = User( - id: authResult.user.uid, - email: email, - fullName: fullName, - userRole: role, - ); - - await _firestoreService.createUser(_currentUser); - await _analyticsService.setUserProperties( - userId: authResult.user.uid, - userRole: _currentUser.userRole, - ); - - return authResult.user != null; - } catch (e) { - return e.message; - } - } - - Future isUserLoggedIn() async { - var user = await _firebaseAuth.currentUser(); - await _populateCurrentUser(user); - return user != null; - } - - Future _populateCurrentUser(FirebaseUser user) async { - if (user != null) { - _currentUser = await _firestoreService.getUser(user.uid); - await _analyticsService.setUserProperties( - userId: user.uid, - userRole: _currentUser.userRole, - ); - } - } -} diff --git a/047-remote-config/lib/services/cloud_storage_service.dart b/047-remote-config/lib/services/cloud_storage_service.dart deleted file mode 100644 index fad3c58b..00000000 --- a/047-remote-config/lib/services/cloud_storage_service.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'dart:io'; - -import 'package:firebase_storage/firebase_storage.dart'; -import 'package:flutter/foundation.dart'; - -class CloudStorageService { - Future uploadImage({ - @required File imageToUpload, - @required String title, - }) async { - var imageFileName = - title + DateTime.now().millisecondsSinceEpoch.toString(); - - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - StorageUploadTask uploadTask = firebaseStorageRef.putFile(imageToUpload); - - StorageTaskSnapshot storageSnapshot = await uploadTask.onComplete; - - var downloadUrl = await storageSnapshot.ref.getDownloadURL(); - - if (uploadTask.isComplete) { - var url = downloadUrl.toString(); - return CloudStorageResult( - imageUrl: url, - imageFileName: imageFileName, - ); - } - - return null; - } - - Future deleteImage(String imageFileName) async { - final StorageReference firebaseStorageRef = - FirebaseStorage.instance.ref().child(imageFileName); - - try { - await firebaseStorageRef.delete(); - return true; - } catch (e) { - return e.toString(); - } - } -} - -class CloudStorageResult { - final String imageUrl; - final String imageFileName; - - CloudStorageResult({this.imageUrl, this.imageFileName}); -} diff --git a/047-remote-config/lib/services/dialog_service.dart b/047-remote-config/lib/services/dialog_service.dart deleted file mode 100644 index a4287595..00000000 --- a/047-remote-config/lib/services/dialog_service.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; - -import 'package:flutter/cupertino.dart'; -import 'package:compound/models/dialog_models.dart'; - -class DialogService { - GlobalKey _dialogNavigationKey = GlobalKey(); - Function(DialogRequest) _showDialogListener; - Completer _dialogCompleter; - - GlobalKey get dialogNavigationKey => _dialogNavigationKey; - - /// Registers a callback function. Typically to show the dialog - void registerDialogListener(Function(DialogRequest) showDialogListener) { - _showDialogListener = showDialogListener; - } - - /// Calls the dialog listener and returns a Future that will wait for dialogComplete. - Future showDialog({ - String title, - String description, - String buttonTitle = 'Ok', - }) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: buttonTitle, - )); - return _dialogCompleter.future; - } - - /// Shows a confirmation dialog - Future showConfirmationDialog( - {String title, - String description, - String confirmationTitle = 'Ok', - String cancelTitle = 'Cancel'}) { - _dialogCompleter = Completer(); - _showDialogListener(DialogRequest( - title: title, - description: description, - buttonTitle: confirmationTitle, - cancelTitle: cancelTitle)); - return _dialogCompleter.future; - } - - /// Completes the _dialogCompleter to resume the Future's execution call - void dialogComplete(DialogResponse response) { - _dialogNavigationKey.currentState.pop(); - _dialogCompleter.complete(response); - _dialogCompleter = null; - } -} diff --git a/047-remote-config/lib/services/dynamic_link_service.dart b/047-remote-config/lib/services/dynamic_link_service.dart deleted file mode 100644 index 3c4ac7db..00000000 --- a/047-remote-config/lib/services/dynamic_link_service.dart +++ /dev/null @@ -1,79 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; - -class DynamicLinkService { - final NavigationService _navigationService = locator(); - - Future handleDynamicLinks() async { - // Get the initial dynamic link if the app is opened with a dynamic link - final PendingDynamicLinkData data = - await FirebaseDynamicLinks.instance.getInitialLink(); - - // handle link that has been retrieved - _handleDeepLink(data); - - // Register a link callback to fire if the app is opened up from the background - // using a dynamic link. - FirebaseDynamicLinks.instance.onLink( - onSuccess: (PendingDynamicLinkData dynamicLink) async { - // handle link that has been retrieved - _handleDeepLink(dynamicLink); - }, onError: (OnLinkErrorException e) async { - print('Link Failed: ${e.message}'); - }); - } - - void _handleDeepLink(PendingDynamicLinkData data) { - final Uri deepLink = data?.link; - if (deepLink != null) { - print('_handleDeepLink | deeplink: $deepLink'); - - var isPost = deepLink.pathSegments.contains('post'); - if (isPost) { - var title = deepLink.queryParameters['title']; - if (title != null) { - _navigationService.navigateTo(CreatePostViewRoute, arguments: title); - } - } - } - } - - Future createFirstPostLink(String title) async { - final DynamicLinkParameters parameters = DynamicLinkParameters( - uriPrefix: 'https://filledstacks.page.link', - link: Uri.parse('https://www.compound.com/post?title=$title'), - androidParameters: AndroidParameters( - packageName: 'com.filledstacks.compound', - ), - - - - - // Other things to add as an example. We don't need it now - iosParameters: IosParameters( - bundleId: 'com.example.ios', - minimumVersion: '1.0.1', - appStoreId: '123456789', - ), - googleAnalyticsParameters: GoogleAnalyticsParameters( - campaign: 'example-promo', - medium: 'social', - source: 'orkut', - ), - itunesConnectAnalyticsParameters: ItunesConnectAnalyticsParameters( - providerToken: '123456', - campaignToken: 'example-promo', - ), - socialMetaTagParameters: SocialMetaTagParameters( - title: 'Example of a Dynamic Link', - description: 'This link works whether app is installed or not!', - ), - ); - - final Uri dynamicUrl = await parameters.buildUrl(); - - return dynamicUrl.toString(); - } -} diff --git a/047-remote-config/lib/services/firestore_service.dart b/047-remote-config/lib/services/firestore_service.dart deleted file mode 100644 index 7f845889..00000000 --- a/047-remote-config/lib/services/firestore_service.dart +++ /dev/null @@ -1,166 +0,0 @@ -import 'dart:async'; - -import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/models/user.dart'; -import 'package:flutter/services.dart'; - -class FirestoreService { - final CollectionReference _usersCollectionReference = - Firestore.instance.collection('users'); - final CollectionReference _postsCollectionReference = - Firestore.instance.collection('posts'); - - final StreamController> _postsController = - StreamController>.broadcast(); - - // #6: Create a list that will keep the paged results - List> _allPagedResults = List>(); - - static const int PostsLimit = 20; - - DocumentSnapshot _lastDocument; - bool _hasMorePosts = true; - - Future createUser(User user) async { - try { - await _usersCollectionReference.document(user.id).setData(user.toJson()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getUser(String uid) async { - try { - var userData = await _usersCollectionReference.document(uid).get(); - return User.fromData(userData.data); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future addPost(Post post) async { - try { - await _postsCollectionReference.add(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Future getPostsOnceOff() async { - try { - var postDocumentSnapshot = - await _postsCollectionReference.limit(PostsLimit).getDocuments(); - if (postDocumentSnapshot.documents.isNotEmpty) { - return postDocumentSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - } - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - Stream listenToPostsRealTime() { - // Register the handler for when the posts data changes - _requestPosts(); - return _postsController.stream; - } - - // #1: Move the request posts into it's own function - void _requestPosts() { - // #2: split the query from the actual subscription - var pagePostsQuery = _postsCollectionReference - .orderBy('title') - // #3: Limit the amount of results - .limit(PostsLimit); - - // #5: If we have a document start the query after it - if (_lastDocument != null) { - pagePostsQuery = pagePostsQuery.startAfterDocument(_lastDocument); - } - - if (!_hasMorePosts) return; - - // #7: Get and store the page index that the results belong to - var currentRequestIndex = _allPagedResults.length; - - pagePostsQuery.snapshots().listen((postsSnapshot) { - if (postsSnapshot.documents.isNotEmpty) { - var posts = postsSnapshot.documents - .map((snapshot) => Post.fromMap(snapshot.data, snapshot.documentID)) - .where((mappedItem) => mappedItem.title != null) - .toList(); - - // #8: Check if the page exists or not - var pageExists = currentRequestIndex < _allPagedResults.length; - - // #9: If the page exists update the posts for that page - if (pageExists) { - _allPagedResults[currentRequestIndex] = posts; - } - // #10: If the page doesn't exist add the page data - else { - _allPagedResults.add(posts); - } - - // #11: Concatenate the full list to be shown - var allPosts = _allPagedResults.fold>(List(), - (initialValue, pageItems) => initialValue..addAll(pageItems)); - - // #12: Broadcase all posts - _postsController.add(allPosts); - - // #13: Save the last document from the results only if it's the current last page - if (currentRequestIndex == _allPagedResults.length - 1) { - _lastDocument = postsSnapshot.documents.last; - } - - // #14: Determine if there's more posts to request - _hasMorePosts = posts.length == PostsLimit; - } - }); - } - - Future deletePost(String documentId) async { - await _postsCollectionReference.document(documentId).delete(); - } - - Future updatePost(Post post) async { - try { - await _postsCollectionReference - .document(post.documentId) - .updateData(post.toMap()); - } catch (e) { - // TODO: Find or create a way to repeat error handling without so much repeated code - if (e is PlatformException) { - return e.message; - } - - return e.toString(); - } - } - - void requestMoreData() => _requestPosts(); -} diff --git a/047-remote-config/lib/services/navigation_service.dart b/047-remote-config/lib/services/navigation_service.dart deleted file mode 100644 index 2344fb42..00000000 --- a/047-remote-config/lib/services/navigation_service.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:flutter/material.dart'; - -class NavigationService { - GlobalKey _navigationKey = GlobalKey(); - - GlobalKey get navigationKey => _navigationKey; - - void pop() { - return _navigationKey.currentState.pop(); - } - - Future navigateTo(String routeName, {dynamic arguments}) { - return _navigationKey.currentState - .pushNamed(routeName, arguments: arguments); - } -} diff --git a/047-remote-config/lib/services/push_notification_service.dart b/047-remote-config/lib/services/push_notification_service.dart deleted file mode 100644 index a7bf9276..00000000 --- a/047-remote-config/lib/services/push_notification_service.dart +++ /dev/null @@ -1,49 +0,0 @@ -import 'dart:io'; - -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:firebase_messaging/firebase_messaging.dart'; - -class PushNotificationService { - final FirebaseMessaging _fcm = FirebaseMessaging(); - final NavigationService _navigationService = locator(); - - Future initialise() async { - if (Platform.isIOS) { - // request permissions if we're on android - _fcm.requestNotificationPermissions(IosNotificationSettings()); - } - - _fcm.configure( - // Called when the app is in the foreground and we receive a push notification - onMessage: (Map message) async { - print('onMessage: $message'); - }, - // Called when the app has been closed comlpetely and it's opened - // from the push notification. - onLaunch: (Map message) async { - print('onLaunch: $message'); - _serialiseAndNavigate(message); - }, - // Called when the app is in the background and it's opened - // from the push notification. - onResume: (Map message) async { - print('onResume: $message'); - _serialiseAndNavigate(message); - }, - ); - } - - void _serialiseAndNavigate(Map message) { - var notificationData = message['data']; - var view = notificationData['view']; - - if (view != null) { - // Navigate to the create post view - if (view == 'create_post') { - _navigationService.navigateTo(CreatePostViewRoute); - } - } - } -} diff --git a/047-remote-config/lib/services/remote_config_service.dart b/047-remote-config/lib/services/remote_config_service.dart deleted file mode 100644 index e76d9c32..00000000 --- a/047-remote-config/lib/services/remote_config_service.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:firebase_remote_config/firebase_remote_config.dart'; - -const String _ShowMainBanner = "show_main_banner"; - -class RemoteConfigService { - final RemoteConfig _remoteConfig; - final defaults = {_ShowMainBanner: false}; - - static RemoteConfigService _instance; - static Future getInstance() async { - if (_instance == null) { - _instance = RemoteConfigService( - remoteConfig: await RemoteConfig.instance, - ); - } - - return _instance; - } - - RemoteConfigService({RemoteConfig remoteConfig}) - : _remoteConfig = remoteConfig; - - bool get showMainBanner => _remoteConfig.getBool(_ShowMainBanner); - - Future initialise() async { - try { - await _remoteConfig.setDefaults(defaults); - await _fetchAndActivate(); - } on FetchThrottledException catch (e) { - print('Remote config fetch throttled: $e'); - } catch (e) { - print( - 'Unable to fetch remote config. Cached or default values will be used'); - } - } - - Future _fetchAndActivate() async { - await _remoteConfig.fetch(); - await _remoteConfig.activateFetched(); - } -} diff --git a/047-remote-config/lib/ui/router.dart b/047-remote-config/lib/ui/router.dart deleted file mode 100644 index b09bc49f..00000000 --- a/047-remote-config/lib/ui/router.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/views/create_post_view.dart'; -import 'package:compound/ui/views/home_view.dart'; -import 'package:flutter/material.dart'; -import 'package:compound/constants/route_names.dart'; -import 'package:compound/ui/views/login_view.dart'; -import 'package:compound/ui/views/signup_view.dart'; - -Route generateRoute(RouteSettings settings) { - switch (settings.name) { - case LoginViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: LoginView(), - ); - case SignUpViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: SignUpView(), - ); - case HomeViewRoute: - return _getPageRoute( - routeName: settings.name, - viewToShow: HomeView(), - ); - case CreatePostViewRoute: - String postTitle; - Post postToEdit; - if (settings.arguments is String) { - postTitle = settings.arguments; - } else if (settings.arguments is Post) { - postToEdit = settings.arguments as Post; - } - - return _getPageRoute( - routeName: settings.name, - viewToShow: CreatePostView( - edittingPost: postToEdit, - postTitle: postTitle, - ), - ); - default: - return MaterialPageRoute( - builder: (_) => Scaffold( - body: Center( - child: Text('No route defined for ${settings.name}')), - )); - } -} - -PageRoute _getPageRoute({String routeName, Widget viewToShow}) { - return MaterialPageRoute( - settings: RouteSettings( - name: routeName, - ), - builder: (_) => viewToShow); -} diff --git a/047-remote-config/lib/ui/shared/app_colors.dart b/047-remote-config/lib/ui/shared/app_colors.dart deleted file mode 100644 index e5ca3a2c..00000000 --- a/047-remote-config/lib/ui/shared/app_colors.dart +++ /dev/null @@ -1,6 +0,0 @@ -import 'package:flutter/material.dart'; - -const Color lightGrey = Color.fromARGB(255,61,63,69); -const Color darkGrey = Color.fromARGB(255,18,18,19); -const Color primaryColor = Color.fromARGB(255, 9, 202, 172); -const Color backgroundColor = Color.fromARGB(255, 26, 27, 30); diff --git a/047-remote-config/lib/ui/shared/shared_styles.dart b/047-remote-config/lib/ui/shared/shared_styles.dart deleted file mode 100644 index c97f570d..00000000 --- a/047-remote-config/lib/ui/shared/shared_styles.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:flutter/material.dart'; - -// Box Decorations - -BoxDecoration fieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[200]); - -BoxDecoration disabledFieldDecortaion = BoxDecoration( - borderRadius: BorderRadius.circular(5), color: Colors.grey[100]); - -// Field Variables - -const double fieldHeight = 55; -const double smallFieldHeight = 40; -const double inputFieldBottomMargin = 30; -const double inputFieldSmallBottomMargin = 0; -const EdgeInsets fieldPadding = const EdgeInsets.symmetric(horizontal: 15); -const EdgeInsets largeFieldPadding = - const EdgeInsets.symmetric(horizontal: 15, vertical: 15); - -// Text Variables -const TextStyle buttonTitleTextStyle = - const TextStyle(fontWeight: FontWeight.w700, color: Colors.white); diff --git a/047-remote-config/lib/ui/shared/ui_helpers.dart b/047-remote-config/lib/ui/shared/ui_helpers.dart deleted file mode 100644 index 1f07ed2c..00000000 --- a/047-remote-config/lib/ui/shared/ui_helpers.dart +++ /dev/null @@ -1,38 +0,0 @@ -import 'package:flutter/material.dart'; - -const Widget horizontalSpaceTiny = SizedBox(width: 5.0); -const Widget horizontalSpaceSmall = SizedBox(width: 10.0); -const Widget horizontalSpaceMedium = SizedBox(width: 25.0); - -const Widget verticalSpaceTiny = SizedBox(height: 5.0); -const Widget verticalSpaceSmall = SizedBox(height: 10.0); -const Widget verticalSpaceMedium = SizedBox(height: 25.0); -const Widget verticalSpaceLarge = SizedBox(height: 50.0); -const Widget verticalSpaceMassive = SizedBox(height: 120.0); - -Widget spacedDivider = Column( - children: const [ - verticalSpaceMedium, - const Divider(color: Colors.blueGrey, height: 5.0), - verticalSpaceMedium, - ], -); - -Widget verticalSpace(double height) => SizedBox(height: height); - -double screenWidth(BuildContext context) => MediaQuery.of(context).size.width; -double screenHeight(BuildContext context) => MediaQuery.of(context).size.height; - -double screenHeightFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenHeight(context) - offsetBy) / dividedBy; - -double screenWidthFraction(BuildContext context, - {int dividedBy = 1, double offsetBy = 0}) => - (screenWidth(context) - offsetBy) / dividedBy; - -double halfScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 2); - -double thirdScreenWidth(BuildContext context) => - screenWidthFraction(context, dividedBy: 3); diff --git a/047-remote-config/lib/ui/views/create_post_view.dart b/047-remote-config/lib/ui/views/create_post_view.dart deleted file mode 100644 index d1255927..00000000 --- a/047-remote-config/lib/ui/views/create_post_view.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:compound/models/post.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/viewmodels/create_post_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class CreatePostView extends StatelessWidget { - final titleController = TextEditingController(); - final Post edittingPost; - final String postTitle; - CreatePostView({ - Key key, - this.edittingPost, - this.postTitle, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => CreatePostViewModel(), - onModelReady: (model) { - if (edittingPost != null) { - // update the text in the controller - titleController.text = edittingPost?.title ?? ''; - - model.setEdittingPost(edittingPost); - } else if (postTitle != null) { - titleController.text = postTitle; - } - }, - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - child: !model.busy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - onPressed: () { - if (!model.busy) { - model.addPost(title: titleController.text); - } - }, - backgroundColor: - !model.busy ? Theme.of(context).primaryColor : Colors.grey[600], - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(40), - Text( - 'Create Post', - style: TextStyle(fontSize: 26), - ), - verticalSpaceMedium, - InputField( - placeholder: 'Title', - controller: titleController, - ), - verticalSpaceMedium, - Text('Post Image'), - verticalSpaceSmall, - GestureDetector( - // When we tap we call selectImage - onTap: () => model.selectImage(), - child: Container( - height: 250, - decoration: BoxDecoration( - color: Colors.grey[200], - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - // If the selected image is null we show "Tap to add post image" - child: model.selectedImage == null - ? Text( - 'Tap to add post image', - style: TextStyle(color: Colors.grey[400]), - ) - // If we have a selected image we want to show it - : Image.file(model.selectedImage), - ), - ) - ], - ), - )), - ); - } -} diff --git a/047-remote-config/lib/ui/views/home_view.dart b/047-remote-config/lib/ui/views/home_view.dart deleted file mode 100644 index ef029fac..00000000 --- a/047-remote-config/lib/ui/views/home_view.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/creation_aware_list_item.dart'; -import 'package:compound/ui/widgets/post_item.dart'; -import 'package:compound/viewmodels/home_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class HomeView extends StatelessWidget { - const HomeView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => HomeViewModel(), - onModelReady: (model) => model.listenToPosts(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - floatingActionButton: FloatingActionButton( - backgroundColor: Theme.of(context).primaryColor, - child: !model.busy - ? Icon(Icons.add) - : Center(child: CircularProgressIndicator()), - onPressed: model.navigateToCreateView, - ), - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 10), - child: Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - verticalSpace(35), - Row( - children: [ - SizedBox( - height: 20, - child: Image.asset('assets/images/title.png'), - ), - ], - ), - if (model.showMainBanner) - Container( - height: 80, - width: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 10), - margin: const EdgeInsets.symmetric(vertical: 15), - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.black12, - blurRadius: 4, - offset: Offset(0, 4)) - ], - color: Colors.white, - borderRadius: BorderRadius.circular(10)), - alignment: Alignment.center, - child: Text( - 'Compound can now share songs directly from Play Music', - textAlign: TextAlign.center, - )), - Expanded( - child: model.posts != null - ? ListView.builder( - itemCount: model.posts.length, - itemBuilder: (context, index) => - CreationAwareListItem( - itemCreated: () { - if (index % 20 == 0) - model.requestMoreData(); - }, - child: GestureDetector( - onTap: () => model.editPost(index), - child: PostItem( - post: model.posts[index], - onDeleteItem: () => - model.deletePost(index), - ), - ), - ), - ) - : Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor), - ), - )) - ], - ), - ), - )); - } -} diff --git a/047-remote-config/lib/ui/views/login_view.dart b/047-remote-config/lib/ui/views/login_view.dart deleted file mode 100644 index c6cb9098..00000000 --- a/047-remote-config/lib/ui/views/login_view.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:compound/ui/widgets/text_link.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/login_view_model.dart'; - -class LoginView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => LoginViewModel(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: 150, - child: Image.asset('assets/images/title.png'), - ), - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - ), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Login', - busy: model.busy, - onPressed: () { - model.login( - email: emailController.text, - password: passwordController.text, - ); - }, - ) - ], - ), - verticalSpaceMedium, - TextLink( - 'Create an Account if you\'re new.', - onPressed: () { - model.navigateToSignUp(); - }, - ) - ], - ), - )), - ); - } -} diff --git a/047-remote-config/lib/ui/views/signup_view.dart b/047-remote-config/lib/ui/views/signup_view.dart deleted file mode 100644 index 75fc82e3..00000000 --- a/047-remote-config/lib/ui/views/signup_view.dart +++ /dev/null @@ -1,77 +0,0 @@ -import 'package:compound/ui/shared/ui_helpers.dart'; -import 'package:compound/ui/widgets/busy_button.dart'; -import 'package:compound/ui/widgets/expansion_list.dart'; -import 'package:compound/ui/widgets/input_field.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; -import 'package:compound/viewmodels/signup_view_model.dart'; - -class SignUpView extends StatelessWidget { - final emailController = TextEditingController(); - final passwordController = TextEditingController(); - final fullNameController = TextEditingController(); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => SignUpViewModel(), - builder: (context, model, child) => Scaffold( - body: Padding( - padding: const EdgeInsets.symmetric(horizontal: 50.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Sign Up', - style: TextStyle( - fontSize: 38, - ), - ), - verticalSpaceLarge, - InputField( - placeholder: 'Full Name', - controller: fullNameController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Email', - controller: emailController, - ), - verticalSpaceSmall, - InputField( - placeholder: 'Password', - password: true, - controller: passwordController, - additionalNote: 'Password has to be a minimum of 6 characters.', - ), - verticalSpaceSmall, - ExpansionList( - items: ['Admin', 'User'], - title: model.selectedRole, - onItemSelected: model.setSelectedRole), - verticalSpaceMedium, - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.end, - children: [ - BusyButton( - title: 'Sign Up', - busy: model.busy, - onPressed: () { - model.signUp( - email: emailController.text, - password: passwordController.text, - fullName: fullNameController.text); - }, - ) - ], - ) - ], - ), - ), - ), - ); - } -} diff --git a/047-remote-config/lib/ui/views/startup_view.dart b/047-remote-config/lib/ui/views/startup_view.dart deleted file mode 100644 index 8edcda39..00000000 --- a/047-remote-config/lib/ui/views/startup_view.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:compound/viewmodels/startup_view_model.dart'; -import 'package:flutter/material.dart'; -import 'package:stacked/stacked.dart'; - -class StartUpView extends StatelessWidget { - const StartUpView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - viewModelBuilder: () => StartUpViewModel(), - onModelReady: (model) => model.handleStartUpLogic(), - builder: (context, model, child) => Scaffold( - backgroundColor: Colors.white, - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - width: 300, - height: 100, - child: Image.asset('assets/images/icon_large.png'), - ), - CircularProgressIndicator( - strokeWidth: 3, - valueColor: AlwaysStoppedAnimation( - Theme.of(context).primaryColor, - ), - ) - ], - ), - ), - ), - ); - } -} diff --git a/047-remote-config/lib/ui/widgets/busy_button.dart b/047-remote-config/lib/ui/widgets/busy_button.dart deleted file mode 100644 index 7843fad5..00000000 --- a/047-remote-config/lib/ui/widgets/busy_button.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:flutter/material.dart'; - -/// A button that shows a busy indicator in place of title -class BusyButton extends StatefulWidget { - final bool busy; - final String title; - final Function onPressed; - final bool enabled; - const BusyButton( - {@required this.title, - this.busy = false, - @required this.onPressed, - this.enabled = true}); - - @override - _BusyButtonState createState() => _BusyButtonState(); -} - -class _BusyButtonState extends State { - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: widget.onPressed, - child: InkWell( - child: AnimatedContainer( - height: widget.busy ? 40 : null, - width: widget.busy ? 40 : null, - duration: const Duration(milliseconds: 300), - alignment: Alignment.center, - padding: EdgeInsets.symmetric( - horizontal: widget.busy ? 10 : 15, - vertical: widget.busy ? 10 : 10), - decoration: BoxDecoration( - color: widget.enabled ? Colors.grey[800] : Colors.grey[300], - borderRadius: BorderRadius.circular(5), - ), - child: !widget.busy - ? Text( - widget.title, - style: buttonTitleTextStyle, - ) - : CircularProgressIndicator( - strokeWidth: 2, - valueColor: AlwaysStoppedAnimation(Colors.white)), - ), - ), - ); - } -} diff --git a/047-remote-config/lib/ui/widgets/busy_overlay.dart b/047-remote-config/lib/ui/widgets/busy_overlay.dart deleted file mode 100644 index 24f0f4b6..00000000 --- a/047-remote-config/lib/ui/widgets/busy_overlay.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'package:flutter/material.dart'; - -/// A modal overlay that will show over your child widget (fullscreen) when the show value is true -/// -/// Wrap your scaffold in this widget and set show value to model.isBusy to show a loading modal when -/// your model state is Busy -class BusyOverlay extends StatelessWidget { - final Widget child; - final String title; - final bool show; - - const BusyOverlay({this.child, - this.title = 'Please wait...', - this.show = false}); - - @override - Widget build(BuildContext context) { - var screenSize = MediaQuery.of(context).size; - return Material( - child: Stack(children: [ - child, - IgnorePointer( - child: Opacity( - opacity: show ? 1.0 : 0.0, - child: Container( - width: screenSize.width, - height: screenSize.height, - alignment: Alignment.center, - color: Color.fromARGB(100, 0, 0, 0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text(title, - style: TextStyle( - fontSize: 16.0, - fontWeight: FontWeight.bold, - color: Colors.white)), - ], - ), - )), - ), - ])); - } -} diff --git a/047-remote-config/lib/ui/widgets/creation_aware_list_item.dart b/047-remote-config/lib/ui/widgets/creation_aware_list_item.dart deleted file mode 100644 index 07739f9c..00000000 --- a/047-remote-config/lib/ui/widgets/creation_aware_list_item.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -class CreationAwareListItem extends StatefulWidget { - final Function itemCreated; - final Widget child; - const CreationAwareListItem({ - Key key, - this.itemCreated, - this.child, - }) : super(key: key); - - @override - _CreationAwareListItemState createState() => _CreationAwareListItemState(); -} - -class _CreationAwareListItemState extends State { - @override - void initState() { - super.initState(); - if (widget.itemCreated != null) { - widget.itemCreated(); - } - } - - @override - Widget build(BuildContext context) { - return widget.child; - } -} diff --git a/047-remote-config/lib/ui/widgets/expansion_list.dart b/047-remote-config/lib/ui/widgets/expansion_list.dart deleted file mode 100644 index c3227d74..00000000 --- a/047-remote-config/lib/ui/widgets/expansion_list.dart +++ /dev/null @@ -1,148 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:compound/ui/shared/shared_styles.dart' as sharedStyles; - -class ExpansionList extends StatefulWidget { - final List items; - final String title; - final Function(dynamic) onItemSelected; - final bool smallVersion; - ExpansionList({ - Key key, - this.items, - this.title, - @required this.onItemSelected, - this.smallVersion = false, - }) : super(key: key); - - _ExpansionListState createState() => _ExpansionListState(); -} - -class _ExpansionListState extends State { - final double startingHeight = sharedStyles.fieldHeight; - double expandedHeight; - bool expanded = false; - String selectedValue; - - @override - void initState() { - super.initState(); - selectedValue = widget.title; - _calculateExpandedHeight(); - } - - @override - Widget build(BuildContext context) { - return AnimatedContainer( - padding: sharedStyles.fieldPadding, - duration: const Duration(milliseconds: 180), - height: expanded - ? expandedHeight - : widget.smallVersion - ? sharedStyles.smallFieldHeight - : startingHeight, - decoration: sharedStyles.fieldDecortaion.copyWith( - boxShadow: expanded - ? [BoxShadow(blurRadius: 10, color: Colors.grey[300])] - : null, - ), - child: ListView( - physics: NeverScrollableScrollPhysics(), - padding: const EdgeInsets.all(0), - children: [ - ExpansionListItem( - title: selectedValue, - onTap: () { - setState(() { - expanded = !expanded; - }); - }, - showArrow: true, - smallVersion: widget.smallVersion, - ), - Container( - height: 2, - color: Colors.grey[300], - ), - ..._getDropdownListItems() - ], - ), - ); - } - - List _getDropdownListItems() { - return widget.items - .map((item) => ExpansionListItem( - smallVersion: widget.smallVersion, - title: item.toString(), - onTap: () { - setState(() { - expanded = !expanded; - selectedValue = item.toString(); - }); - - widget.onItemSelected(item); - })) - .toList(); - } - - void _calculateExpandedHeight() { - expandedHeight = 2 + - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight) + - (widget.items.length * - (widget.smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight)); - } -} - -class ExpansionListItem extends StatelessWidget { - final Function onTap; - final String title; - final bool showArrow; - final bool smallVersion; - const ExpansionListItem({ - Key key, - this.onTap, - this.title, - this.showArrow = false, - this.smallVersion = false, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: onTap, - child: Container( - height: smallVersion - ? sharedStyles.smallFieldHeight - : sharedStyles.fieldHeight, - alignment: Alignment.centerLeft, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Expanded( - child: Text( - title ?? '', - style: Theme.of(context) - .textTheme - .subtitle1 - .copyWith(fontSize: smallVersion ? 12 : 15), - ), - ), - showArrow - ? Icon( - Icons.arrow_drop_down, - color: Colors.grey[700], - size: 20, - ) - : Container() - ], - ), - ), - ); - } -} diff --git a/047-remote-config/lib/ui/widgets/input_field.dart b/047-remote-config/lib/ui/widgets/input_field.dart deleted file mode 100644 index e25b1ad0..00000000 --- a/047-remote-config/lib/ui/widgets/input_field.dart +++ /dev/null @@ -1,123 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:compound/ui/shared/shared_styles.dart'; -import 'package:compound/ui/shared/ui_helpers.dart'; - -import 'note_text.dart'; - -class InputField extends StatefulWidget { - final TextEditingController controller; - final TextInputType textInputType; - final bool password; - final bool isReadOnly; - final String placeholder; - final String validationMessage; - final Function enterPressed; - final bool smallVersion; - final FocusNode fieldFocusNode; - final FocusNode nextFocusNode; - final TextInputAction textInputAction; - final String additionalNote; - final Function(String) onChanged; - final TextInputFormatter formatter; - - InputField( - {@required this.controller, - @required this.placeholder, - this.enterPressed, - this.fieldFocusNode, - this.nextFocusNode, - this.additionalNote, - this.onChanged, - this.formatter, - this.validationMessage, - this.textInputAction = TextInputAction.next, - this.textInputType = TextInputType.text, - this.password = false, - this.isReadOnly = false, - this.smallVersion = false}); - - @override - _InputFieldState createState() => _InputFieldState(); -} - -class _InputFieldState extends State { - bool isPassword; - double fieldHeight = 55; - - @override - void initState() { - super.initState(); - isPassword = widget.password; - } - - @override - Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - height: widget.smallVersion ? 40 : fieldHeight, - alignment: Alignment.centerLeft, - padding: fieldPadding, - decoration: - widget.isReadOnly ? disabledFieldDecortaion : fieldDecortaion, - child: Row( - children: [ - Expanded( - child: TextFormField( - controller: widget.controller, - keyboardType: widget.textInputType, - focusNode: widget.fieldFocusNode, - textInputAction: widget.textInputAction, - onChanged: widget.onChanged, - inputFormatters: - widget.formatter != null ? [widget.formatter] : null, - onEditingComplete: () { - if (widget.enterPressed != null) { - FocusScope.of(context).requestFocus(FocusNode()); - widget.enterPressed(); - } - }, - onFieldSubmitted: (value) { - if (widget.nextFocusNode != null) { - widget.nextFocusNode.requestFocus(); - } - }, - obscureText: isPassword, - readOnly: widget.isReadOnly, - decoration: InputDecoration.collapsed( - hintText: widget.placeholder, - hintStyle: - TextStyle(fontSize: widget.smallVersion ? 12 : 15)), - ), - ), - GestureDetector( - onTap: () => setState(() { - isPassword = !isPassword; - }), - child: widget.password - ? Container( - width: fieldHeight, - height: fieldHeight, - alignment: Alignment.center, - child: Icon(isPassword - ? Icons.visibility - : Icons.visibility_off)) - : Container(), - ), - ], - ), - ), - if (widget.validationMessage != null) - NoteText( - widget.validationMessage, - color: Colors.red, - ), - if (widget.additionalNote != null) verticalSpace(5), - if (widget.additionalNote != null) NoteText(widget.additionalNote), - verticalSpaceSmall - ], - ); - } -} diff --git a/047-remote-config/lib/ui/widgets/note_text.dart b/047-remote-config/lib/ui/widgets/note_text.dart deleted file mode 100644 index 90d8e1d1..00000000 --- a/047-remote-config/lib/ui/widgets/note_text.dart +++ /dev/null @@ -1,21 +0,0 @@ -import 'package:flutter/material.dart'; - -class NoteText extends StatelessWidget { - final String text; - final TextAlign textAlign; - final Color color; - const NoteText(this.text, {this.textAlign, this.color}); - - @override - Widget build(BuildContext context) { - return Text( - text, - textAlign: textAlign, - style: TextStyle( - fontSize: 12, - fontWeight: FontWeight.normal, - color: color ?? Colors.grey[600], - ), - ); - } -} diff --git a/047-remote-config/lib/ui/widgets/post_item.dart b/047-remote-config/lib/ui/widgets/post_item.dart deleted file mode 100644 index f8580fac..00000000 --- a/047-remote-config/lib/ui/widgets/post_item.dart +++ /dev/null @@ -1,64 +0,0 @@ -import 'package:cached_network_image/cached_network_image.dart'; -import 'package:compound/models/post.dart'; -import 'package:flutter/material.dart'; - -class PostItem extends StatelessWidget { - final Post post; - final Function onDeleteItem; - const PostItem({ - Key key, - this.post, - this.onDeleteItem, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - return Container( - height: post.imageUrl != null ? null : 60, - margin: const EdgeInsets.only(top: 20), - alignment: Alignment.center, - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.only(left: 15.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - // If the image is not null load the imageURL - post.imageUrl != null - ? SizedBox( - height: 250, - child: CachedNetworkImage( - imageUrl: post.imageUrl, - placeholder: (context, url) => - CircularProgressIndicator(), - errorWidget: (context, url, error) => - Icon(Icons.error), - ), - ) - // If the image is null show nothing - : Container(), - Text(post.title), - ], - ), - )), - IconButton( - icon: Icon(Icons.close), - onPressed: () { - if (onDeleteItem != null) { - onDeleteItem(); - } - }, - ), - ], - ), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(5), - boxShadow: [ - BoxShadow(blurRadius: 8, color: Colors.grey[200], spreadRadius: 3) - ]), - ); - } -} diff --git a/047-remote-config/lib/ui/widgets/text_link.dart b/047-remote-config/lib/ui/widgets/text_link.dart deleted file mode 100644 index 7c214fed..00000000 --- a/047-remote-config/lib/ui/widgets/text_link.dart +++ /dev/null @@ -1,18 +0,0 @@ -import 'package:flutter/material.dart'; - -class TextLink extends StatelessWidget { - final String text; - final Function onPressed; - const TextLink(this.text, {this.onPressed}); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onPressed, - child: Text( - text, - style: TextStyle(fontWeight: FontWeight.w700, fontSize: 14), - ), - ); - } -} diff --git a/047-remote-config/lib/utils/image_selector.dart b/047-remote-config/lib/utils/image_selector.dart deleted file mode 100644 index df91fc25..00000000 --- a/047-remote-config/lib/utils/image_selector.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:image_picker/image_picker.dart'; - -class ImageSelector { - Future selectImage() async { - return await ImagePicker().getImage(source: ImageSource.gallery); - } -} diff --git a/047-remote-config/lib/viewmodels/base_model.dart b/047-remote-config/lib/viewmodels/base_model.dart deleted file mode 100644 index 078de524..00000000 --- a/047-remote-config/lib/viewmodels/base_model.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:compound/locator.dart'; -import 'package:compound/models/user.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/remote_config_service.dart'; -import 'package:flutter/widgets.dart'; - -class BaseModel extends ChangeNotifier { - final AuthenticationService _authenticationService = - locator(); - final RemoteConfigService _remoteConfigService = - locator(); - - User get currentUser => _authenticationService.currentUser; - - // Since it'll most likely be used in almost every view we expose it here - bool get showMainBanner => _remoteConfigService.showMainBanner; - - bool _busy = false; - bool get busy => _busy; - - void setBusy(bool value) { - _busy = value; - notifyListeners(); - } -} diff --git a/047-remote-config/lib/viewmodels/create_post_view_model.dart b/047-remote-config/lib/viewmodels/create_post_view_model.dart deleted file mode 100644 index f84026f0..00000000 --- a/047-remote-config/lib/viewmodels/create_post_view_model.dart +++ /dev/null @@ -1,91 +0,0 @@ -import 'dart:io'; - -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/utils/image_selector.dart'; -import 'package:compound/viewmodels/base_model.dart'; -import 'package:flutter/foundation.dart'; - -class CreatePostViewModel extends BaseModel { - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final ImageSelector _imageSelector = locator(); - final CloudStorageService _cloudStorageService = - locator(); - final AnalyticsService _analyticsService = locator(); - - File _selectedImage; - File get selectedImage => _selectedImage; - - Post _edittingPost; - - bool get _editting => _edittingPost != null; - - Future selectImage() async { - var tempImage = await _imageSelector.selectImage(); - if (tempImage != null) { - _selectedImage = File(tempImage.path); - notifyListeners(); - } - } - - Future addPost({@required String title}) async { - setBusy(true); - - CloudStorageResult storageResult; - - if (!_editting) { - storageResult = await _cloudStorageService.uploadImage( - imageToUpload: _selectedImage, - title: title, - ); - } - - var result; - - if (!_editting) { - result = await _firestoreService.addPost(Post( - title: title, - userId: currentUser.id, - imageUrl: storageResult.imageUrl, - imageFileName: storageResult.imageFileName, - )); - - await _analyticsService.logPostCreated(hasImage: _selectedImage != null); - } else { - result = await _firestoreService.updatePost(Post( - title: title, - userId: _edittingPost.userId, - documentId: _edittingPost.documentId, - imageUrl: _edittingPost.imageUrl, - imageFileName: _edittingPost.imageFileName, - )); - } - - setBusy(false); - - if (result is String) { - await _dialogService.showDialog( - title: 'Cound not create post', - description: result, - ); - } else { - await _dialogService.showDialog( - title: 'Post successfully Added', - description: 'Your post has been created', - ); - } - - _navigationService.pop(); - } - - void setEdittingPost(Post edittingPost) { - _edittingPost = edittingPost; - } -} diff --git a/047-remote-config/lib/viewmodels/home_view_model.dart b/047-remote-config/lib/viewmodels/home_view_model.dart deleted file mode 100644 index 9d3fa639..00000000 --- a/047-remote-config/lib/viewmodels/home_view_model.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/models/post.dart'; -import 'package:compound/services/cloud_storage_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/firestore_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class HomeViewModel extends BaseModel { - final NavigationService _navigationService = locator(); - final FirestoreService _firestoreService = locator(); - final DialogService _dialogService = locator(); - final CloudStorageService _cloudStorageService = - locator(); - - List _posts; - List get posts => _posts; - - void listenToPosts() { - setBusy(true); - - _firestoreService.listenToPostsRealTime().listen((postsData) { - List updatedPosts = postsData; - if (updatedPosts != null && updatedPosts.length > 0) { - _posts = updatedPosts; - notifyListeners(); - } - - setBusy(false); - }); - } - - Future deletePost(int index) async { - var dialogResponse = await _dialogService.showConfirmationDialog( - title: 'Are you sure?', - description: 'Do you really want to delete the post?', - confirmationTitle: 'Yes', - cancelTitle: 'No', - ); - - if (dialogResponse.confirmed) { - var postToDelete = _posts[index]; - setBusy(true); - await _firestoreService.deletePost(postToDelete.documentId); - // Delete the image after the post is deleted - await _cloudStorageService.deleteImage(postToDelete.imageFileName); - setBusy(false); - } - } - - Future navigateToCreateView() async { - await _navigationService.navigateTo(CreatePostViewRoute); - } - - void editPost(int index) { - _navigationService.navigateTo(CreatePostViewRoute, - arguments: _posts[index]); - } - - void requestMoreData() => _firestoreService.requestMoreData(); -} diff --git a/047-remote-config/lib/viewmodels/login_view_model.dart b/047-remote-config/lib/viewmodels/login_view_model.dart deleted file mode 100644 index a557a91a..00000000 --- a/047-remote-config/lib/viewmodels/login_view_model.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class LoginViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - Future login({ - @required String email, - @required String password, - }) async { - setBusy(true); - - var result = await _authenticationService.loginWithEmail( - email: email, - password: password, - ); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logLogin(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: 'General login failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Login Failure', - description: result, - ); - } - } - - void navigateToSignUp() { - _navigationService.navigateTo(SignUpViewRoute); - } -} diff --git a/047-remote-config/lib/viewmodels/signup_view_model.dart b/047-remote-config/lib/viewmodels/signup_view_model.dart deleted file mode 100644 index b23ed4d2..00000000 --- a/047-remote-config/lib/viewmodels/signup_view_model.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/analytics_service.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dialog_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:flutter/foundation.dart'; - -import 'base_model.dart'; - -class SignUpViewModel extends BaseModel { - final AuthenticationService _authenticationService = - locator(); - final DialogService _dialogService = locator(); - final NavigationService _navigationService = locator(); - final AnalyticsService _analyticsService = locator(); - - String _selectedRole = 'Select a User Role'; - String get selectedRole => _selectedRole; - - void setSelectedRole(dynamic role) { - _selectedRole = role; - notifyListeners(); - } - - Future signUp({ - @required String email, - @required String password, - @required String fullName, - }) async { - setBusy(true); - - var result = await _authenticationService.signUpWithEmail( - email: email, - password: password, - fullName: fullName, - role: _selectedRole); - - setBusy(false); - - if (result is bool) { - if (result) { - await _analyticsService.logSignUp(); - _navigationService.navigateTo(HomeViewRoute); - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: 'General sign up failure. Please try again later', - ); - } - } else { - await _dialogService.showDialog( - title: 'Sign Up Failure', - description: result, - ); - } - } -} diff --git a/047-remote-config/lib/viewmodels/startup_view_model.dart b/047-remote-config/lib/viewmodels/startup_view_model.dart deleted file mode 100644 index fb3e4c70..00000000 --- a/047-remote-config/lib/viewmodels/startup_view_model.dart +++ /dev/null @@ -1,40 +0,0 @@ -import 'package:compound/constants/route_names.dart'; -import 'package:compound/locator.dart'; -import 'package:compound/services/authentication_service.dart'; -import 'package:compound/services/dynamic_link_service.dart'; -import 'package:compound/services/navigation_service.dart'; -import 'package:compound/services/push_notification_service.dart'; -import 'package:compound/services/remote_config_service.dart'; -import 'package:compound/viewmodels/base_model.dart'; - -class StartUpViewModel extends BaseModel { - // We'll be looking at Dependency Injection during our architecture review. - // The next series will be on the refined and reviewed Mvvm architecture. - // Dependency injection over service location is something that we're looking - // at. VERY EXCITED ABOUT THE ARCHITECTURE UPDATES. We've built 6 apps with the current one - // it works very well but there are some improvements that can be made. - - final AuthenticationService _authenticationService = - locator(); - final NavigationService _navigationService = locator(); - final PushNotificationService _pushNotificationService = - locator(); - final DynamicLinkService _dynamicLinkService = locator(); - final RemoteConfigService _remoteConfigService = locator(); - - Future handleStartUpLogic() async { - await _dynamicLinkService.handleDynamicLinks(); - await _remoteConfigService.initialise(); - - // Register for push notifications - await _pushNotificationService.initialise(); - - var hasLoggedInUser = await _authenticationService.isUserLoggedIn(); - - if (hasLoggedInUser) { - _navigationService.navigateTo(HomeViewRoute); - } else { - _navigationService.navigateTo(LoginViewRoute); - } - } -} diff --git a/047-remote-config/pubspec.lock b/047-remote-config/pubspec.lock deleted file mode 100644 index 26d53dbd..00000000 --- a/047-remote-config/pubspec.lock +++ /dev/null @@ -1,621 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _flutterfire_internals: - dependency: transitive - description: - name: _flutterfire_internals - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.10" - async: - dependency: "direct main" - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.9.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - cached_network_image: - dependency: "direct main" - description: - name: cached_network_image - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.3" - cached_network_image_platform_interface: - dependency: transitive - description: - name: cached_network_image_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" - cached_network_image_web: - dependency: transitive - description: - name: cached_network_image_web - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - cloud_firestore: - dependency: "direct main" - description: - name: cloud_firestore - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - cloud_firestore_platform_interface: - dependency: transitive - description: - name: cloud_firestore_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "5.9.1" - cloud_firestore_web: - dependency: transitive - description: - name: cloud_firestore_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.16.0" - cross_file: - dependency: transitive - description: - name: cross_file - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.3+2" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.4" - firebase_analytics: - dependency: "direct main" - description: - name: firebase_analytics - url: "https://pub.dartlang.org" - source: hosted - version: "5.0.15" - firebase_analytics_platform_interface: - dependency: transitive - description: - name: firebase_analytics_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - firebase_auth: - dependency: "direct main" - description: - name: firebase_auth - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.0" - firebase_auth_platform_interface: - dependency: transitive - description: - name: firebase_auth_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "6.11.4" - firebase_auth_web: - dependency: transitive - description: - name: firebase_auth_web - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.0" - firebase_core: - dependency: transitive - description: - name: firebase_core - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0" - firebase_core_platform_interface: - dependency: transitive - description: - name: firebase_core_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.5.2" - firebase_core_web: - dependency: transitive - description: - name: firebase_core_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" - firebase_dynamic_links: - dependency: "direct main" - description: - name: firebase_dynamic_links - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.1" - firebase_messaging: - dependency: "direct main" - description: - name: firebase_messaging - url: "https://pub.dartlang.org" - source: hosted - version: "14.1.4" - firebase_messaging_platform_interface: - dependency: transitive - description: - name: firebase_messaging_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.8" - firebase_messaging_web: - dependency: transitive - description: - name: firebase_messaging_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.9" - firebase_remote_config: - dependency: "direct main" - description: - name: firebase_remote_config - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.1" - firebase_storage: - dependency: "direct main" - description: - name: firebase_storage - url: "https://pub.dartlang.org" - source: hosted - version: "11.0.7" - firebase_storage_platform_interface: - dependency: transitive - description: - name: firebase_storage_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.25" - firebase_storage_web: - dependency: transitive - description: - name: firebase_storage_web - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.17" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.0" - flutter_cache_manager: - dependency: transitive - description: - name: flutter_cache_manager - url: "https://pub.dartlang.org" - source: hosted - version: "3.3.0" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.7" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "2.14.1" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - http: - dependency: "direct main" - description: - name: http - url: "https://pub.dartlang.org" - source: hosted - version: "0.13.5" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.2" - image_picker: - dependency: "direct main" - description: - name: image_picker - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6" - image_picker_android: - dependency: transitive - description: - name: image_picker_android - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.5+3" - image_picker_for_web: - dependency: transitive - description: - name: image_picker_for_web - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.10" - image_picker_ios: - dependency: transitive - description: - name: image_picker_ios - url: "https://pub.dartlang.org" - source: hosted - version: "0.8.6+1" - image_picker_platform_interface: - dependency: transitive - description: - name: image_picker_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.6.2" - injectable: - dependency: transitive - description: - name: injectable - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0+1" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.17.0" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.12" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - octo_image: - dependency: transitive - description: - name: octo_image - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.2" - path_provider: - dependency: transitive - description: - name: path_provider - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_android: - dependency: transitive - description: - name: path_provider_android - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.22" - path_provider_ios: - dependency: transitive - description: - name: path_provider_ios - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.11" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.6" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.5" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.11.1" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "4.2.4" - provider: - dependency: "direct main" - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.1.3" - rxdart: - dependency: transitive - description: - name: rxdart - url: "https://pub.dartlang.org" - source: hosted - version: "0.27.7" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.0" - sqflite: - dependency: transitive - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.2" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - url: "https://pub.dartlang.org" - source: hosted - version: "2.4.0+2" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.3" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.0+3" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.12" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1" - uuid: - dependency: transitive - description: - name: uuid - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.7" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.2" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.2" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0+2" -sdks: - dart: ">=2.18.0 <3.0.0" - flutter: ">=3.3.0" diff --git a/047-remote-config/pubspec.yaml b/047-remote-config/pubspec.yaml deleted file mode 100644 index 824b0555..00000000 --- a/047-remote-config/pubspec.yaml +++ /dev/null @@ -1,91 +0,0 @@ -name: compound -description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.2.2 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.3 - # http request - http: ">=0.12.1 <0.14.0" - # async package to add additional Cancellable operations - async: ^2.4.1 - # get it - get_it: ^4.0.2 - # provider - provider: ^4.1.3 - # Stacked Arch - stacked: ^1.6.0 - stacked_services: ^0.4.3 - firebase_auth: ">=0.16.1 <5.0.0" - cloud_firestore: ">=0.13.6 <5.0.0" - firebase_storage: ">=3.1.6 <12.0.0" - image_picker: ">=0.6.7+2 <0.9.0" - cached_network_image: ">=2.2.0+1 <4.0.0" - - firebase_messaging: ">=6.0.16 <15.0.0" - firebase_analytics: ^5.0.15 - firebase_dynamic_links: ^0.5.1 - firebase_remote_config: ^0.3.1 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/title.png - - assets/images/icon_large.png - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - fonts: - - family: Open Sans - fonts: - - asset: assets/fonts/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/OpenSans-Regular.ttf - weight: 400 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages diff --git a/057-sqlite-and-migrations/.gitignore b/057-sqlite-and-migrations/.gitignore deleted file mode 100644 index 9d532b18..00000000 --- a/057-sqlite-and-migrations/.gitignore +++ /dev/null @@ -1,41 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.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 diff --git a/057-sqlite-and-migrations/.metadata b/057-sqlite-and-migrations/.metadata deleted file mode 100644 index ee5762c1..00000000 --- a/057-sqlite-and-migrations/.metadata +++ /dev/null @@ -1,10 +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: d408d302e22179d598f467e11da5dd968dbdc9ec - channel: stable - -project_type: app diff --git a/057-sqlite-and-migrations/README.md b/057-sqlite-and-migrations/README.md deleted file mode 100644 index 651afc12..00000000 --- a/057-sqlite-and-migrations/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# sqflite_migration_example - -A new Flutter project. - -## Getting Started - -This project is a starting point for a Flutter application. - -A few resources to get you started if this is your first Flutter project: - -- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) -- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) - -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. diff --git a/057-sqlite-and-migrations/assets/sql/1_create_schema.sql b/057-sqlite-and-migrations/assets/sql/1_create_schema.sql deleted file mode 100644 index 819779d2..00000000 --- a/057-sqlite-and-migrations/assets/sql/1_create_schema.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE todos( - id INTEGER PRIMARY KEY, - title TEXT, - complete INT -); \ No newline at end of file diff --git a/057-sqlite-and-migrations/assets/sql/2_add_description.sql b/057-sqlite-and-migrations/assets/sql/2_add_description.sql deleted file mode 100644 index a300e01c..00000000 --- a/057-sqlite-and-migrations/assets/sql/2_add_description.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE todos ADD description TEXT; \ No newline at end of file diff --git a/057-sqlite-and-migrations/lib/app/locator.dart b/057-sqlite-and-migrations/lib/app/locator.dart deleted file mode 100644 index 9b5c7ee6..00000000 --- a/057-sqlite-and-migrations/lib/app/locator.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'package:get_it/get_it.dart'; -import 'package:sqflite_migration_example/services/database_service.dart'; -import 'package:sqflite_migration_service/sqflite_migration_service.dart'; -import 'package:stacked_services/stacked_services.dart'; - -final locator = GetIt.instance; - -void setupLocator() { - locator.registerLazySingleton(() => NavigationService()); - locator.registerLazySingleton(() => DatabaseService()); - locator.registerLazySingleton(() => DatabaseMigrationService()); -} diff --git a/057-sqlite-and-migrations/lib/main.dart b/057-sqlite-and-migrations/lib/main.dart deleted file mode 100644 index 223168f0..00000000 --- a/057-sqlite-and-migrations/lib/main.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:sqflite_migration_example/app/locator.dart'; -import 'package:sqflite_migration_example/ui/router.dart' as router; -import 'package:sqflite_migration_example/ui/startup/startup_view.dart'; -import 'package:stacked_services/stacked_services.dart'; - -void main() { - setupLocator(); - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - - - return MaterialApp( - title: 'Flutter Demo', - navigatorKey: locator().navigatorKey, - home: StartupView(), - onGenerateRoute: router.Router.onGenerateRoute, - ); - } -} diff --git a/057-sqlite-and-migrations/lib/models/todo.dart b/057-sqlite-and-migrations/lib/models/todo.dart deleted file mode 100644 index bc754ca2..00000000 --- a/057-sqlite-and-migrations/lib/models/todo.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:freezed_annotation/freezed_annotation.dart'; - -part 'todo.freezed.dart'; -part 'todo.g.dart'; - -@freezed -abstract class Todo with _$Todo { - Todo._(); - - factory Todo({ - int id, - @required String title, - String description, - @Default(0) int complete, - }) = _Todo; - - factory Todo.fromJson(Map json) => _$TodoFromJson(json); - - bool get isComplete => complete == 1 ? true : false; -} diff --git a/057-sqlite-and-migrations/lib/models/todo.freezed.dart b/057-sqlite-and-migrations/lib/models/todo.freezed.dart deleted file mode 100644 index 1a273d4c..00000000 --- a/057-sqlite-and-migrations/lib/models/todo.freezed.dart +++ /dev/null @@ -1,198 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND -// ignore_for_file: deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies - -part of 'todo.dart'; - -// ************************************************************************** -// FreezedGenerator -// ************************************************************************** - -T _$identity(T value) => value; -Todo _$TodoFromJson(Map json) { - return _Todo.fromJson(json); -} - -/// @nodoc -class _$TodoTearOff { - const _$TodoTearOff(); - -// ignore: unused_element - _Todo call( - {int id, @required String title, String description, int complete = 0}) { - return _Todo( - id: id, - title: title, - description: description, - complete: complete, - ); - } - -// ignore: unused_element - Todo fromJson(Map json) { - return Todo.fromJson(json); - } -} - -/// @nodoc -// ignore: unused_element -const $Todo = _$TodoTearOff(); - -/// @nodoc -mixin _$Todo { - int get id; - String get title; - String get description; - int get complete; - - Map toJson(); - $TodoCopyWith get copyWith; -} - -/// @nodoc -abstract class $TodoCopyWith<$Res> { - factory $TodoCopyWith(Todo value, $Res Function(Todo) then) = - _$TodoCopyWithImpl<$Res>; - $Res call({int id, String title, String description, int complete}); -} - -/// @nodoc -class _$TodoCopyWithImpl<$Res> implements $TodoCopyWith<$Res> { - _$TodoCopyWithImpl(this._value, this._then); - - final Todo _value; - // ignore: unused_field - final $Res Function(Todo) _then; - - @override - $Res call({ - Object id = freezed, - Object title = freezed, - Object description = freezed, - Object complete = freezed, - }) { - return _then(_value.copyWith( - id: id == freezed ? _value.id : id as int, - title: title == freezed ? _value.title : title as String, - description: - description == freezed ? _value.description : description as String, - complete: complete == freezed ? _value.complete : complete as int, - )); - } -} - -/// @nodoc -abstract class _$TodoCopyWith<$Res> implements $TodoCopyWith<$Res> { - factory _$TodoCopyWith(_Todo value, $Res Function(_Todo) then) = - __$TodoCopyWithImpl<$Res>; - @override - $Res call({int id, String title, String description, int complete}); -} - -/// @nodoc -class __$TodoCopyWithImpl<$Res> extends _$TodoCopyWithImpl<$Res> - implements _$TodoCopyWith<$Res> { - __$TodoCopyWithImpl(_Todo _value, $Res Function(_Todo) _then) - : super(_value, (v) => _then(v as _Todo)); - - @override - _Todo get _value => super._value as _Todo; - - @override - $Res call({ - Object id = freezed, - Object title = freezed, - Object description = freezed, - Object complete = freezed, - }) { - return _then(_Todo( - id: id == freezed ? _value.id : id as int, - title: title == freezed ? _value.title : title as String, - description: - description == freezed ? _value.description : description as String, - complete: complete == freezed ? _value.complete : complete as int, - )); - } -} - -@JsonSerializable() - -/// @nodoc -class _$_Todo extends _Todo { - _$_Todo({this.id, @required this.title, this.description, this.complete = 0}) - : assert(title != null), - assert(complete != null), - super._(); - - factory _$_Todo.fromJson(Map json) => - _$_$_TodoFromJson(json); - - @override - final int id; - @override - final String title; - @override - final String description; - @JsonKey(defaultValue: 0) - @override - final int complete; - - @override - String toString() { - return 'Todo(id: $id, title: $title, description: $description, complete: $complete)'; - } - - @override - bool operator ==(dynamic other) { - return identical(this, other) || - (other is _Todo && - (identical(other.id, id) || - const DeepCollectionEquality().equals(other.id, id)) && - (identical(other.title, title) || - const DeepCollectionEquality().equals(other.title, title)) && - (identical(other.description, description) || - const DeepCollectionEquality() - .equals(other.description, description)) && - (identical(other.complete, complete) || - const DeepCollectionEquality() - .equals(other.complete, complete))); - } - - @override - int get hashCode => - runtimeType.hashCode ^ - const DeepCollectionEquality().hash(id) ^ - const DeepCollectionEquality().hash(title) ^ - const DeepCollectionEquality().hash(description) ^ - const DeepCollectionEquality().hash(complete); - - @override - _$TodoCopyWith<_Todo> get copyWith => - __$TodoCopyWithImpl<_Todo>(this, _$identity); - - @override - Map toJson() { - return _$_$_TodoToJson(this); - } -} - -abstract class _Todo extends Todo { - _Todo._() : super._(); - factory _Todo( - {int id, - @required String title, - String description, - int complete}) = _$_Todo; - - factory _Todo.fromJson(Map json) = _$_Todo.fromJson; - - @override - int get id; - @override - String get title; - @override - String get description; - @override - int get complete; - @override - _$TodoCopyWith<_Todo> get copyWith; -} diff --git a/057-sqlite-and-migrations/lib/models/todo.g.dart b/057-sqlite-and-migrations/lib/models/todo.g.dart deleted file mode 100644 index 7c8082a3..00000000 --- a/057-sqlite-and-migrations/lib/models/todo.g.dart +++ /dev/null @@ -1,23 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'todo.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -_$_Todo _$_$_TodoFromJson(Map json) { - return _$_Todo( - id: json['id'] as int, - title: json['title'] as String, - description: json['description'] as String, - complete: json['complete'] as int ?? 0, - ); -} - -Map _$_$_TodoToJson(_$_Todo instance) => { - 'id': instance.id, - 'title': instance.title, - 'description': instance.description, - 'complete': instance.complete, - }; diff --git a/057-sqlite-and-migrations/lib/services/database_service.dart b/057-sqlite-and-migrations/lib/services/database_service.dart deleted file mode 100644 index 38ca289f..00000000 --- a/057-sqlite-and-migrations/lib/services/database_service.dart +++ /dev/null @@ -1,62 +0,0 @@ -import 'package:sqflite/sqflite.dart'; -import 'package:sqflite_migration_example/app/locator.dart'; -import 'package:sqflite_migration_example/models/todo.dart'; -import 'package:sqflite_migration_service/sqflite_migration_service.dart'; - -const String DB_NAME = 'todo_database.sqlite'; - -const String TodoTableName = 'todos'; - -class DatabaseService { - final _migrationService = locator(); - - Database _database; - Future initialise() async { - _database = await openDatabase(DB_NAME, version: 1); - - await _migrationService.runMigration( - _database, - migrationFiles: [ - '1_create_schema.sql', - '2_add_description.sql', - ], - verbose: true, - ); - } - - Future> getTodos() async { - // Get all the data from the TodoTableName - List todoResults = await _database.query(TodoTableName); - // Map data to a Todo object - return todoResults.map((todo) => Todo.fromJson(todo)).toList(); - } - - Future addTodo({String title, String description}) async { - try { - await _database.insert( - TodoTableName, - Todo( - title: title, - description: description, - ).toJson(), - ); - } catch (e) { - print('Could not insert the todo: $e'); - } - } - - Future updateCompleteForTodo({int id, bool complete}) async { - try { - await _database.update( - TodoTableName, - // We only pass in the data we want to update. - // The field used here already has to exist in the schema - {'complete': complete ? 1 : 0}, - where: 'id = ?', - whereArgs: [id], - ); - } catch (e) { - print('Could not update the todo with id:$id. $e'); - } - } -} diff --git a/057-sqlite-and-migrations/lib/ui/router.dart b/057-sqlite-and-migrations/lib/ui/router.dart deleted file mode 100644 index 63430479..00000000 --- a/057-sqlite-and-migrations/lib/ui/router.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:sqflite_migration_example/ui/todo/todo_view.dart'; - -/// Function created using the router setup found in the below FilledStacks article. -/// https://www.filledstacks.com/post/flutter-navigation-cheatsheet-a-guide-to-named-routing/#setup-a-router-for-named-routing - -class Router { - static Route onGenerateRoute(RouteSettings settings) { - switch (settings.name) { - case todo: - default: - return MaterialPageRoute(builder: (context) => TodoView()); - } - } - - static const todo = 'todo'; -} diff --git a/057-sqlite-and-migrations/lib/ui/startup/startup_view.dart b/057-sqlite-and-migrations/lib/ui/startup/startup_view.dart deleted file mode 100644 index 18cbc769..00000000 --- a/057-sqlite-and-migrations/lib/ui/startup/startup_view.dart +++ /dev/null @@ -1,30 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:sqflite_migration_example/ui/startup/startup_viewmodel.dart'; -import 'package:stacked/stacked.dart'; - -/// [StartupView] will be shown right after the native splash screen -/// and will initialise everything required for the app to function. -/// -/// After initialisation the ViewModel will navigate to the intended view -class StartupView extends StatelessWidget { - const StartupView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ViewModelBuilder.reactive( - builder: (context, model, child) => Scaffold( - body: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - CircularProgressIndicator(), - Text('Preparing app ... '), - ], - ), - ), - ), - viewModelBuilder: () => StartupViewModel(), - onModelReady: (model) => model.initialise(), - ); - } -} diff --git a/057-sqlite-and-migrations/lib/ui/startup/startup_viewmodel.dart b/057-sqlite-and-migrations/lib/ui/startup/startup_viewmodel.dart deleted file mode 100644 index e528d9be..00000000 --- a/057-sqlite-and-migrations/lib/ui/startup/startup_viewmodel.dart +++ /dev/null @@ -1,16 +0,0 @@ -import 'package:sqflite_migration_example/app/locator.dart'; -import 'package:sqflite_migration_example/services/database_service.dart'; -import 'package:stacked/stacked.dart'; -import 'package:stacked_services/stacked_services.dart'; - -import '../router.dart'; - -class StartupViewModel extends BaseViewModel { - final _navigationService = locator(); - final _databaseService = locator(); - - Future initialise() async { - await _databaseService.initialise(); - await _navigationService.navigateTo(Router.todo); - } -} diff --git a/057-sqlite-and-migrations/lib/ui/todo/todo_view.dart b/057-sqlite-and-migrations/lib/ui/todo/todo_view.dart deleted file mode 100644 index 98e6c74b..00000000 --- a/057-sqlite-and-migrations/lib/ui/todo/todo_view.dart +++ /dev/null @@ -1,90 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_hooks/flutter_hooks.dart'; -import 'package:sqflite_migration_example/ui/todo/todo_viewmodel.dart'; -import 'package:stacked/stacked.dart'; - -class TodoView extends HookWidget { - const TodoView({Key key}) : super(key: key); - - @override - Widget build(BuildContext context) { - var todoController = useTextEditingController(); - var descriptionController = useTextEditingController(); - - return ViewModelBuilder.reactive( - builder: (context, model, child) => Scaffold( - floatingActionButton: FloatingActionButton( - onPressed: () async { - model.addTodo(todoController.text, descriptionController.text); - todoController.clear(); - descriptionController.clear(); - }, - child: !model.isBusy - ? Icon(Icons.add) - : CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation(Colors.white), - ), - ), - body: SizedBox( - height: MediaQuery.of(context).size.height, - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - SizedBox(height: 60), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 25), - child: TextField( - controller: todoController, - decoration: InputDecoration(hintText: 'Add a todo'), - ), - ), - Padding( - padding: const EdgeInsets.symmetric(horizontal: 25), - child: TextField( - controller: descriptionController, - decoration: InputDecoration(hintText: 'Add a description'), - ), - ), - if (model.dataReady && model.data.isNotEmpty) - Expanded( - child: ListView.builder( - itemCount: model.data.length, - itemBuilder: (context, index) => Container( - padding: const EdgeInsets.symmetric(horizontal: 25), - height: 40, - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(model.data[index].title), - Text( - model.data[index].description ?? '', - style: TextStyle( - color: Colors.grey, - ), - ), - ], - ), - Checkbox( - value: model.data[index].isComplete, - onChanged: (value) => - model.setCompleteForItem(index, value), - ) - ], - ), - ), - ), - ), - if (model.dataReady && model.data.isEmpty) - Text('No todo\'s yet. Add some'), - ], - ), - ), - ), - viewModelBuilder: () => TodoViewModel(), - ); - } -} diff --git a/057-sqlite-and-migrations/lib/ui/todo/todo_viewmodel.dart b/057-sqlite-and-migrations/lib/ui/todo/todo_viewmodel.dart deleted file mode 100644 index 25ec98df..00000000 --- a/057-sqlite-and-migrations/lib/ui/todo/todo_viewmodel.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:sqflite_migration_example/app/locator.dart'; -import 'package:sqflite_migration_example/models/todo.dart'; -import 'package:sqflite_migration_example/services/database_service.dart'; -import 'package:stacked/stacked.dart'; - -class TodoViewModel extends FutureViewModel> { - final _databaseService = locator(); - - Future addTodo(String title, String description) async { - await _databaseService.addTodo(title: title, description: description); - - // Initialise will rerun the initial FutureViewModel logic which will - // 1. Run the Future provided to futureToRun() - // 2. Store the value returned from that future in the data property - await initialise(); - } - - @override - Future> futureToRun() => _databaseService.getTodos(); - - Future setCompleteForItem(int index, bool value) async { - await _databaseService.updateCompleteForTodo( - id: data[index].id, - complete: value, - ); - - // Initialise will rerun the initial FutureViewModel logic which will - // 1. Run the Future provided to futureToRun() - // 2. Store the value returned from that future in the data property - await initialise(); - } -} diff --git a/057-sqlite-and-migrations/pubspec.lock b/057-sqlite-and-migrations/pubspec.lock deleted file mode 100644 index 35c36740..00000000 --- a/057-sqlite-and-migrations/pubspec.lock +++ /dev/null @@ -1,740 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - _fe_analyzer_shared: - dependency: transitive - description: - name: _fe_analyzer_shared - url: "https://pub.dartlang.org" - source: hosted - version: "7.0.0" - analyzer: - dependency: transitive - description: - name: analyzer - url: "https://pub.dartlang.org" - source: hosted - version: "0.39.17" - args: - dependency: transitive - description: - name: args - url: "https://pub.dartlang.org" - source: hosted - version: "1.6.0" - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.5.0-nullsafety.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.1" - build: - dependency: transitive - description: - name: build - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - build_config: - dependency: transitive - description: - name: build_config - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.2" - build_daemon: - dependency: transitive - description: - name: build_daemon - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - build_resolvers: - dependency: transitive - description: - name: build_resolvers - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.11" - build_runner: - dependency: "direct dev" - description: - name: build_runner - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.2" - build_runner_core: - dependency: transitive - description: - name: build_runner_core - url: "https://pub.dartlang.org" - source: hosted - version: "6.0.1" - built_collection: - dependency: transitive - description: - name: built_collection - url: "https://pub.dartlang.org" - source: hosted - version: "4.3.2" - built_value: - dependency: transitive - description: - name: built_value - url: "https://pub.dartlang.org" - source: hosted - version: "7.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.3" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety.1" - checked_yaml: - dependency: transitive - description: - name: checked_yaml - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.1" - code_builder: - dependency: transitive - description: - name: code_builder - url: "https://pub.dartlang.org" - source: hosted - version: "3.4.1" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.15.0-nullsafety.3" - convert: - dependency: transitive - description: - name: convert - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.1" - crypto: - dependency: transitive - description: - name: crypto - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.5" - csslib: - dependency: transitive - description: - name: csslib - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.2" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.0" - dart_style: - dependency: transitive - description: - name: dart_style - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.6" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety.1" - ffi: - dependency: transitive - description: - name: ffi - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.3" - file: - dependency: transitive - description: - name: file - url: "https://pub.dartlang.org" - source: hosted - version: "5.2.1" - fixnum: - dependency: transitive - description: - name: fixnum - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.11" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_hooks: - dependency: "direct main" - description: - name: flutter_hooks - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.1" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_web_plugins: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - freezed: - dependency: "direct dev" - description: - name: freezed - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.1" - freezed_annotation: - dependency: "direct main" - description: - name: freezed_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.0" - get: - dependency: transitive - description: - name: get - url: "https://pub.dartlang.org" - source: hosted - version: "3.12.1" - get_core: - dependency: transitive - description: - name: get_core - url: "https://pub.dartlang.org" - source: hosted - version: "3.12.0" - get_instance: - dependency: transitive - description: - name: get_instance - url: "https://pub.dartlang.org" - source: hosted - version: "3.12.0" - get_it: - dependency: "direct main" - description: - name: get_it - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.4" - get_navigation: - dependency: transitive - description: - name: get_navigation - url: "https://pub.dartlang.org" - source: hosted - version: "3.12.0" - get_rx: - dependency: transitive - description: - name: get_rx - url: "https://pub.dartlang.org" - source: hosted - version: "3.12.0" - get_state_manager: - dependency: transitive - description: - name: get_state_manager - url: "https://pub.dartlang.org" - source: hosted - version: "3.12.0" - get_utils: - dependency: transitive - description: - name: get_utils - url: "https://pub.dartlang.org" - source: hosted - version: "3.12.0" - glob: - dependency: transitive - description: - name: glob - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - graphs: - dependency: transitive - description: - name: graphs - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.0" - html: - dependency: transitive - description: - name: html - url: "https://pub.dartlang.org" - source: hosted - version: "0.14.0+4" - http_multi_server: - dependency: transitive - description: - name: http_multi_server - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0" - http_parser: - dependency: transitive - description: - name: http_parser - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.4" - intl: - dependency: transitive - description: - name: intl - url: "https://pub.dartlang.org" - source: hosted - version: "0.16.1" - io: - dependency: transitive - description: - name: io - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.4" - js: - dependency: transitive - description: - name: js - url: "https://pub.dartlang.org" - source: hosted - version: "0.6.2" - json_annotation: - dependency: "direct main" - description: - name: json_annotation - url: "https://pub.dartlang.org" - source: hosted - version: "3.1.0" - json_serializable: - dependency: "direct dev" - description: - name: json_serializable - url: "https://pub.dartlang.org" - source: hosted - version: "3.5.0" - logging: - dependency: transitive - description: - name: logging - url: "https://pub.dartlang.org" - source: hosted - version: "0.11.4" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.10-nullsafety.1" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.3" - mime: - dependency: transitive - description: - name: mime - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7" - nested: - dependency: transitive - description: - name: nested - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4" - node_interop: - dependency: transitive - description: - name: node_interop - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - node_io: - dependency: transitive - description: - name: node_io - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" - observable_ish: - dependency: transitive - description: - name: observable_ish - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.4" - package_config: - dependency: transitive - description: - name: package_config - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.3" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety.1" - path_provider_linux: - dependency: transitive - description: - name: path_provider_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+2" - path_provider_platform_interface: - dependency: transitive - description: - name: path_provider_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - path_provider_windows: - dependency: transitive - description: - name: path_provider_windows - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.4+1" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.9.2" - platform: - dependency: transitive - description: - name: platform - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" - plugin_platform_interface: - dependency: transitive - description: - name: plugin_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - pool: - dependency: transitive - description: - name: pool - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.0" - process: - dependency: transitive - description: - name: process - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.13" - provider: - dependency: transitive - description: - name: provider - url: "https://pub.dartlang.org" - source: hosted - version: "4.3.2+2" - pub_semver: - dependency: transitive - description: - name: pub_semver - url: "https://pub.dartlang.org" - source: hosted - version: "1.4.4" - pubspec_parse: - dependency: transitive - description: - name: pubspec_parse - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.5" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.3" - shared_preferences: - dependency: transitive - description: - name: shared_preferences - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.12+2" - shared_preferences_linux: - dependency: transitive - description: - name: shared_preferences_linux - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.2+2" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+10" - shared_preferences_platform_interface: - dependency: transitive - description: - name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.4" - shared_preferences_web: - dependency: transitive - description: - name: shared_preferences_web - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+7" - shared_preferences_windows: - dependency: transitive - description: - name: shared_preferences_windows - url: "https://pub.dartlang.org" - source: hosted - version: "0.0.1+1" - shelf: - dependency: transitive - description: - name: shelf - url: "https://pub.dartlang.org" - source: hosted - version: "0.7.9" - shelf_web_socket: - dependency: transitive - description: - name: shelf_web_socket - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.3" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_gen: - dependency: transitive - description: - name: source_gen - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7+1" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0-nullsafety.2" - sqflite: - dependency: "direct main" - description: - name: sqflite - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.1+1" - sqflite_common: - dependency: transitive - description: - name: sqflite_common - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.2+1" - sqflite_migration_service: - dependency: "direct main" - description: - name: sqflite_migration_service - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0-nullsafety.1" - stacked: - dependency: "direct main" - description: - name: stacked - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.6" - stacked_services: - dependency: "direct main" - description: - name: stacked_services - url: "https://pub.dartlang.org" - source: hosted - version: "0.5.4+4" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.1" - stream_transform: - dependency: transitive - description: - name: stream_transform - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0-nullsafety.1" - synchronized: - dependency: transitive - description: - name: synchronized - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.0+2" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0-nullsafety.1" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.19-nullsafety.2" - timing: - dependency: transitive - description: - name: timing - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.1+2" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0-nullsafety.3" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0-nullsafety.3" - watcher: - dependency: transitive - description: - name: watcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.9.7+15" - web_socket_channel: - dependency: transitive - description: - name: web_socket_channel - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - win32: - dependency: transitive - description: - name: win32 - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.3" - xdg_directories: - dependency: transitive - description: - name: xdg_directories - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" - yaml: - dependency: transitive - description: - name: yaml - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.1" -sdks: - dart: ">=2.10.0-110 <2.11.0" - flutter: ">=1.20.0 <2.0.0" diff --git a/057-sqlite-and-migrations/pubspec.yaml b/057-sqlite-and-migrations/pubspec.yaml deleted file mode 100644 index 3ec5fc9f..00000000 --- a/057-sqlite-and-migrations/pubspec.yaml +++ /dev/null @@ -1,94 +0,0 @@ -name: sqflite_migration_example -description: A new Flutter project. - -# The following line prevents the package from being accidentally published to -# pub.dev using `pub publish`. This is preferred for private packages. -publish_to: "none" # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.7.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.0 - - # Application framework - stacked: - stacked_services: - flutter_hooks: - - # data models - freezed_annotation: - json_annotation: ^3.0.1 - - # Service location - get_it: - - # Database - sqflite: ^1.3.1+1 - sqflite_migration_service: ^1.0.1 - -dev_dependencies: - flutter_test: - sdk: flutter - - build_runner: - freezed: - json_serializable: ^3.2.5 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/sql/ - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/057-sqlite-and-migrations/test/widget_test.dart b/057-sqlite-and-migrations/test/widget_test.dart deleted file mode 100644 index 0508f7fa..00000000 --- a/057-sqlite-and-migrations/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:sqflite_migration_example/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/067-sliver-guide/.gitignore b/067-sliver-guide/.gitignore deleted file mode 100644 index 0fa6b675..00000000 --- a/067-sliver-guide/.gitignore +++ /dev/null @@ -1,46 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.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 - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release diff --git a/067-sliver-guide/.metadata b/067-sliver-guide/.metadata deleted file mode 100644 index 56bfc2c4..00000000 --- a/067-sliver-guide/.metadata +++ /dev/null @@ -1,10 +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: f4abaa0735eba4dfd8f33f73363911d63931fe03 - channel: stable - -project_type: app diff --git a/067-sliver-guide/lib/main.dart b/067-sliver-guide/lib/main.dart deleted file mode 100644 index 55e3cd96..00000000 --- a/067-sliver-guide/lib/main.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; - -void main() { - runApp(MyApp()); -} - -class MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: Scaffold( - body: CustomScrollView( - slivers: [ - ...List.generate(5, (index) => index).map( - (e) => SliverToBoxAdapter( - child: Container( - height: 300, - color: Colors.red, - margin: const EdgeInsets.symmetric(vertical: 5), - ), - ), - ), - StickySliver( - child: Container( - height: 400, - color: Colors.purple, - ), - ), - ...List.generate(5, (index) => index).map( - (e) => SliverToBoxAdapter( - child: Container( - height: 300, - color: Colors.red, - margin: const EdgeInsets.symmetric(vertical: 10), - ), - ), - ) - ], - ), - ), - ); - } -} - -class RenderStickySliver extends RenderSliverSingleBoxAdapter { - RenderStickySliver({RenderBox? child}) : super(child: child); - - @override - void performLayout() { - var myCurrentConstraints = constraints; - - geometry = SliverGeometry.zero; - - child?.layout( - constraints.asBoxConstraints(), - parentUsesSize: true, - ); - - double childExtent = child?.size.height ?? 0; - - geometry = SliverGeometry( - paintExtent: childExtent, - maxPaintExtent: childExtent, - paintOrigin: constraints.scrollOffset, - ); - - setChildParentData(child!, constraints, geometry!); - } -} - -class StickySliver extends SingleChildRenderObjectWidget { - StickySliver({Widget? child, Key? key}) : super(child: child, key: key); - - @override - RenderObject createRenderObject(BuildContext context) { - return RenderStickySliver(); - } -} diff --git a/067-sliver-guide/pubspec.lock b/067-sliver-guide/pubspec.lock deleted file mode 100644 index 7ffced4e..00000000 --- a/067-sliver-guide/pubspec.lock +++ /dev/null @@ -1,153 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - url: "https://pub.dartlang.org" - source: hosted - version: "2.6.1" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - characters: - dependency: transitive - description: - name: characters - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - charcode: - dependency: transitive - description: - name: charcode - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - clock: - dependency: transitive - description: - name: clock - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - collection: - dependency: transitive - description: - name: collection - url: "https://pub.dartlang.org" - source: hosted - version: "1.15.0" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.3" - fake_async: - dependency: transitive - description: - name: fake_async - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - matcher: - dependency: transitive - description: - name: matcher - url: "https://pub.dartlang.org" - source: hosted - version: "0.12.10" - meta: - dependency: transitive - description: - name: meta - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - path: - dependency: transitive - description: - name: path - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - url: "https://pub.dartlang.org" - source: hosted - version: "1.8.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "1.10.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - string_scanner: - dependency: transitive - description: - name: string_scanner - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" - term_glyph: - dependency: transitive - description: - name: term_glyph - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.0" - test_api: - dependency: transitive - description: - name: test_api - url: "https://pub.dartlang.org" - source: hosted - version: "0.3.0" - typed_data: - dependency: transitive - description: - name: typed_data - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.0" - vector_math: - dependency: transitive - description: - name: vector_math - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" -sdks: - dart: ">=2.12.0 <3.0.0" diff --git a/067-sliver-guide/pubspec.yaml b/067-sliver-guide/pubspec.yaml deleted file mode 100644 index fdb7dc57..00000000 --- a/067-sliver-guide/pubspec.yaml +++ /dev/null @@ -1,76 +0,0 @@ -name: sliver_guide -description: A new Flutter project. - -# The following line prevents the package from being accidentally published to -# pub.dev using `pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ">=2.12.0 <3.0.0" - -dependencies: - flutter: - sdk: flutter - - - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.2 - -dev_dependencies: - flutter_test: - sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - # assets: - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages diff --git a/067-sliver-guide/test/widget_test.dart b/067-sliver-guide/test/widget_test.dart deleted file mode 100644 index c82b1761..00000000 --- a/067-sliver-guide/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:sliver_guide/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/LICENSE b/LICENSE index b5d3bb17..de5b3bac 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2019 Dane Mackier - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +MIT License + +Copyright (c) 2019 Dane Mackier + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 554ba516..e72af513 100644 --- a/README.md +++ b/README.md @@ -1,155 +1,37 @@ -# Flutter tutorials - -The repo contains the source code for all the written tutorials by Filledstacks. - -All Tutorials plus additional snippets and shorter posts can be found on the [Official FilledStacks website](https://www.filledstacks.com/). - -## Products - -[Flutter Web Mastery course](https://dane-mackier-s-school.teachable.com/p/master-flutter-on-the-web) - -## \*\* Important \*\* - -When you want to run any of the code first run - -``` -flutter create . -``` - -In the repo to generate the platform projects for the tutorials. - -## Tutorials - -**087 - How to Build a Flutter Website in 2023** \[ [Video](https://youtu.be/yvn6I9hzsJs) \] \[ [Source](https://github.com/FilledStacks/academy/tree/tutorials/02-nested-routing-start) \] \[ [Written](https://www.filledstacks.com/post/how-to-build-a-flutter-website-in-2023/) \] - The updated tutorial for building a Flutter Website - -**086 - Flutter Website Nested Layouts and Custom URL's** \[ [Video](https://youtu.be/cGdNRnBdWpw) \] \[ [Source](https://github.com/FilledStacks/academy/tree/tutorials/02-nested-routing) \] - The updated tutorial for building a Flutter Website - -**085 - 6 Tips to Make your Flutter Website feel Premium** \[ [Video](https://youtu.be/ZFx9leiFlvM) \] \[ [Written](https://www.filledstacks.com/post/6-tips-to-make-your-flutter-website-feel-premium/) \] - 6 Tips you can apply to immediately make your Flutter Website feel more premium - -**066 - Login and Create Account Implementation** \[ [Video](https://youtu.be/Y-JawJ4m6Fg) \] \[ [Source](https://github.com/FilledStacks/boxtout/tree/main/src/clients/customer) \] \[ [Written](https://www.filledstacks.com/post/building-flutter-login-and-sign-up-forms/) \] - This tutorial goes over implementation we'll be using for Login and Create Account functionality. - -**064 - New Improved Stacked Setup** \[ [Video](https://youtu.be/1WW8xHhZvyA) \] \[ [Source](https://github.com/FilledStacks/boxtout/tree/main/src/clients/customer) \] - This tutorial goes over the new and improved stacked setup that includes navigation, dependency registration and the traditional stacked statemanagement. - -**063 - Firebase Authentication in 5 minutes** \[ [Video](https://youtu.be/2YZrXEHrvBI) \] \[ [Source](https://github.com/FilledStacks/boxtout/tree/main/src/clients/customer) \] - In this tutorial we setup the firebase authentication for a flutter app in 5 minutes - -**062 - Code overview for Firebase Backend** \[ [Video](https://youtu.be/ImjeP6Ts8JI) \] - This tutorial goes over the code required to build a scalable firebase backend - -**061 - Planning a Firebase Backend** \[ [Video](https://youtu.be/nj21LXUUhyo) \] - In this tutorial we go over a detailed plan for building a scalable backend using Firebase Cloud Functions. - -**060 - Making Technical decisions** \[ [Video](https://youtu.be/Ly6_gkY4sUQ) \] - In this tutorial we go over the thinking and reasoning behind making some of the technical decisions required when planning for a large scale product development - -**059 - Planning a Food Delivery Service** \[ [Video](https://youtu.be/8nVnrdFFBWw) \] - This tutorial goes over the planning for a food delivery product - -**058 - Bottom Sheet Service | Using Flutter Bottom Sheets without context** \[ [Video](https://youtu.be/OvBl-j59bOg) \] \[ [Written](https://www.filledstacks.com/post/bottom-sheets-in-flutter-through-stacked-services/) \] \[ [Source](https://github.com/FilledStacks/stacked-example/tree/part-8-bottom-sheet-service) \] - This tutorial goes over the usage of the new BottomSheetService in the stacked_services package. - -**057 - SQLite in Flutter | Migrations and Schema Management** \[ [Video](https://youtu.be/yR37lWE6xO4) \] \[ [Written](https://www.filledstacks.com/post/sq-lite-in-flutter/) \] - This tutorial goes over the SQLite implementation used in our production applications. It shows the basics of SQLite. The meat of the tutorial comes from the schema management solution we use. - -**055 - Lottie Splash Screen in Flutter** \[ [Video](https://youtu.be/YcUip0Y8CUg) \] \[ [Written](https://www.filledstacks.com/post/lottie-splash-screen-intro-in-flutter/) \] - A tutorial that shows you how to implement an animated splash screen using Lottie and delay the navigation until it's complete. - -**054 - Flutter Architecture Part 7 - Dialog Service** \[ [Video](https://youtu.be/uuyJHCxxMEY) \] \[ [Written](https://www.filledstacks.com/post/show-dialogs-without-context/) \] \[ [Source Code](https://github.com/FilledStacks/stacked-example/tree/part-7-dialog-service) \] - A complete guide to the setup of the basics for a starter stacked architecture project. - -**053 - Flutter Architecture Part 6 - Bottom Navigation with Stacked** \[ [Video](https://youtu.be/OBIrqm0LDaA) \] \[ [Written](https://www.filledstacks.com/post/bottom-navigation-with-stacked-architecture/) \] \[ [Source Code](https://github.com/FilledStacks/stacked-example/tree/part-6-bottom-nav) \] - A guide to implementing a bottom navigation bar using stacked. - -**052 - Flutter Architecture Part 5 - How to Mock - Unit Testing** \[ [Video](https://youtu.be/Kq-YMAE1ssA) \] \[ [Written](https://www.filledstacks.com/post/how-to-mock-for-unit-testing/) \] \[ [Source Code](https://github.com/FilledStacks/stacked-example/tree/part-5-mocking-unit-tests) \] - A complete guide to mocking in unit testing, how it's used for tests and what they're used for. - -**051 - Flutter Architecture Part 4 - How to Unit test a Unit Testing intro** \[ [Video](https://youtu.be/n21w5T3jdWE) \] \[ [Written](https://www.filledstacks.com/post/how-to-unit-test-in-flutter/) \] \[ [Source Code](https://github.com/FilledStacks/stacked-example/tree/part-4-unit-testing-1) \] - An intro to unit testing and how to set it up in Flutter. - -**050 - Flutter Architecture Part 3 - Flutter Services** \[ [Video](https://youtu.be/UoZQS1bkNTw) \] \[ [Written](https://www.filledstacks.com/post/services-in-code-and-how-to-use-them-in-flutter/) \] \[ [Source Code](https://github.com/FilledStacks/stacked-example/tree/part-3-services) \] - A complete guide on services, service classes, what they are used for and how to use them. - -**049 - Flutter Architecture Part 2 - Stacked State Management scenarios** \[ [Video](https://youtu.be/hEy_36LPcgQ) \] \[ [Written](https://www.filledstacks.com/post/flutter-and-provider-architecture-using-stacked/) \] \[ [Source Code](https://github.com/FilledStacks/stacked-example/tree/part-2-stacked-statemanagement) \] - This tutorial goes over common state management situation encountered in a real world application - -**048 - Flutter Architecture Part 1 - Stacked, Routing and GetIt setup** \[ [Video](https://youtu.be/DO8le1W_HqQ) \] \[ [Written](https://www.filledstacks.com/post/flutter-and-provider-architecture-using-stacked/) \] \[ [Source Code](https://github.com/FilledStacks/stacked-example/tree/part1-setup) \] - A complete guide to the setup of the basics for a starter stacked architecture project. - -**047 - Firebase and Flutter Part 10 - Remote Config** \[ [Video](https://youtu.be/mPghiKYKUV4) \] \[ [Written](https://www.filledstacks.com/post/remote-config-in-flutter/) \] - This tutorial goes over remote config and how to manage it in a flutter project. - -**046 - Firebase and Flutter Part 9 - Dynamic Links in Flutter** \[ [Video](https://youtu.be/aBrRJqrQTpQ) \] \[ [Written](https://www.filledstacks.com/post/dynamic-links-in-flutter-a-complete-guide/) \] - This tutorial covers the use of dynamic links in flutter to perform auto routing and deep linking. - -**045 - Firebase and Flutter Part 8 - Realtime Paginated Data using Firestore** \[ [Video](https://youtu.be/1chV50D5BVU) \] \[ [Written](https://www.filledstacks.com/post/how-to-perform-real-time-pagination-with-firestore/) \] - This tutorial shows the implementation of getting real time firebase data when impelementing an infinte scrolling view. - -**044 - Firebase and Flutter Part 7 - Analytics** \[ [Video](https://youtu.be/31KpJXqCayo) \] \[ [Written](https://www.filledstacks.com/post/firebase-analytics-and-metrics-in-flutter/) \] - This tutorial shows you how to add analytics into your Flutter app for live monitoring of your users. - -**043 - Firebase and Flutter Part 6 - Push Notifications using Cloud Messaging** \[ [Video](https://youtu.be/Lq9-DPKWtIc) \] \[ [Written](https://www.filledstacks.com/post/push-notifications-in-flutter-using-firebase/) \] - This tutorial goes over my implementation of Push Notification in Flutter using Firebase Cloud Messaging. - -**042 - Firebase and Flutter - Part 5 - Firebase Cloud Storage** \[[Video](https://youtu.be/WDqi-ZUXHEo) \] \[ [Written](https://www.filledstacks.com/post/firebase-cloud-storage-in-flutter/) \] - In this tutorial we go over the implementation details of using Firebase Cloud Storage inside a Flutter application. - -**041 - Firebase and Flutter - Part 4 - Firestore Security Rules** \[ [Video](https://youtu.be/8rRr9GnynR0) \] \[ [Written](https://www.filledstacks.com/post/firestore-security-rules-with-testing/) \] - This tutorial covers the implementation of Firestore security rules and how to test them. - -**040 - Firebase and Flutter - Part 3 - CRUD using Firestore** \[ [Video](https://youtu.be/1PhAPWzGaM4) \] \[ [Written](https://filledstacks.firebaseapp.com/post/firestore-crud-in-flutter/) \] - This tutorial goes over the CRUD implementation using Firestore. We Create documents, Read the collection, Delete documents and Update existing documents data through Flutter. - -**039 - Firebase and Flutter - Part 2 - Custom Startup Logic and User Profiles** \[ [Video](https://youtu.be/d6FaV7cp_YE) \] \[ [Written](https://www.filledstacks.com/post/firebase-startup-logic-and-custom-user-profiles/) \] - This tutorial goes over the process of making sure we startup on the correct view and the logic behind adding a custom user profile. - -**038 - Firebase and Flutter - Part 1 - Basic Authentication** \[ [Video](https://youtu.be/tKET5s_Vu-c) \] \[ [Written](https://www.filledstacks.com/post/firebase-authentication-in-flutter/) \] - This tutorial covers the setup of a firebase project and the basic functionality to perform a login / sign up using Firebase email authentication. - -**037 - Flutter Web Development - Part 6 - Advanced URL navigation** \[ [Video](https://youtu.be/q-n1Q98s92s) \] \[ [Written](https://www.filledstacks.com/post/flutter-web-advanced-navigation/) \] - In this video we cover URL navigation in Flutter Web that allows us to navigation within a template and pass in query parameters. - -**036 - Flutter Web Development - Part 5 - Hover Effects** \[ [Video](https://youtu.be/VABcKZLpvyg) \] \[ [Written](https://www.filledstacks.com/post/flutter-web-hover-and-mouse-cursor/) \] - This video goes over how to add hover effects into Flutter Web. - -**035 - Flutter Web Development - Part 4 - State and API integration** \[ [Video](https://youtu.be/qailF0Ut_c0) \] \[ [Written](https://www.filledstacks.com/post/flutter-api-integration/) \] - In this video we integrate the provider_architecture package and create a simple API class to fetch our data. - -**034 - Flutter Web Development - Part 3 - Template Layouts** \[ [Video](https://youtu.be/nw2c6YI1Sb8) \] \[ [Written](https://www.filledstacks.com/post/template-layouts-and-navigation-in-flutter-web/) \] - This tutorial contains the code for a Flutter Template Layout for Web Development. - -**033 - Flutter Web Development - Part 2 - Responsive UI** \[ [Video](https://youtu.be/Kl69yxukBdw) \] \[ [Written](https://www.filledstacks.com/post/building-a-responsive-website-using-flutter/) \] - This guide goes over adding responsiveness to your Flutter web UI - -**032 - Flutter Web Development - Part 1** \[ [Video](https://youtu.be/XmBuwm-GhNc) \] \[ [Written](https://www.filledstacks.com/post/create-and-deploy-a-flutter-web-app/) \] - In this tutorial we create a Flutter web app, build a basic UI and deploy it to firestore. - -**031 - Flutter Responsive UI - Part 3** \[ [Video](https://youtu.be/HUSqk0OrR7I) \] \[ [Written](https://www.filledstacks.com/post/a-responsive-ui-architecture-solution-with-provider/) \] - This tutorial goes over the process of adding Provider on top of an existing Responsive UI framework for state management. - -**030 - Flutter Responsive UI - Part 2** \[ [Video](https://youtu.be/udsysUj-X4w) \] \[ [Written](https://www.filledstacks.com/post/building-a-responsive-ui-architecture-in-flutter/) \] - This tutorial / guide goes over how you can build a responsive UI architecture to allow for a maintainable and manageable multi platform code base. - -**029 - Flutter Responsive UI - Part 1** \[ [Video](https://youtu.be/z7P1OFLw4kY) \] \[ [Written](https://www.filledstacks.com/post/the-best-flutter-responsive-ui-pattern/) \] - This tutorial goes over the process of building a base widget that provides us with all the information to build a responsive UI. - -**028 - Flutter Continuous Scroll** \[ [Video](https://youtu.be/rr7d3SuhLiU) \] \[ [Written](https://www.filledstacks.com/post/flutter-infinite-scroll-using-flutter-only/) \] - This tutorial goes over how to create a continuous scrolling list in Flutter using index numbers and not the scroll controller. - -**027 - Flutter Location Service** \[ [Video](https://youtu.be/UdBUe_NP-BI) \] \[ [Written](https://www.filledstacks.com/snippet/build-a-flutter-location-service) \] - This tutorial covers the should be common task of wrapping a set of functionality within a service. We build a location service that provides continuous updates using the Location package. - -**026 - Flutter stream basics. Absolute basics** \[ [Video](https://youtu.be/53jIxLiCv2E) \] \[ [Written](https://www.filledstacks.com/post/a-complete-guide-to-flutter-streams) \] - This is a short tutorial that covers the creation, usage and management of streams. I also cover how to manually create Streams using `async*` functionality. - -**025 - Flutter navigation without BuildContext | Navigation Service** \[ [Video](https://youtu.be/kopdISefbJc) \] \[ [Written](http://filledstacks.com/post/navigate-without-build-context-in-flutter-using-a-navigation-service) \] - This tutorial covers the creation of a Navigation Service to move your navigation logic out of your UI files into the business logic files. - -**024 - Abstraction in Flutter Pt2 | Better unit tests using Abstraction** \[ [Video](https://youtu.be/oZW3Eb3J9s0) \] \[ [Written](https://www.filledstacks.com/post/better-unit-tests-in-flutter-using-abstraction) \] - In this tutorial we go over how using Abstraction can make your unit tests better. - -**023 - Abstraction In Flutter Pt1 | How it can save hours of development time** \[ [Video](https://youtu.be/n2yGl7vJJGM) \] \[ [Written](https://www.filledstacks.com/post/develop-faster-in-flutter-using-abstraction) \] - This tutorial is part one of the abstraction series that will cover the benefits of abstraction in practical use cases. In this one we look at how using a second implementation of an interface that returns fake data can speed up your application development. - -**022 - Build a Lifecycle manager for Background behaviour in Flutter** \[ [Video](https://youtu.be/NfvA-7-HzYk) \] \[ [Written](https://www.filledstacks.com/post/flutter-application-life-cycle-management) \] - In this tutorial I go over how to build and hook up a LifeCycle manager to the Flutter AppLifeCycle. We use that to start and stop services within our architecture when the app enters a background state or come back to the foreground. - -**021 - Build an architecture for your dialog management in Flutter** \[ [Video](https://youtu.be/IrFU_BrCWnE) \] \[ [Written](https://www.filledstacks.com/post/manager-your-flutter-dialogs-with-a-dialog-manager) \] - This tutorial guides you on how to create a dialog manager in Flutter that allows you to show and access information from dialogs from your business logic. - -**020 - A Guide to using Futures** \[ [Video](https://youtu.be/DAS0EQuM-oU) \] \[ [Written](https://www.filledstacks.com/post/complete-beginners-guide-to-futures) \] - This tutorial goes over the functionality provided by Futures and how to use it. - -**019 - Flutter animation Guide | Deep Dive | Flutter Hooks and Flutter Sequence Builder** \[ [Written](https://www.filledstacks.com/post/flutter-animation-guide-flutter-hooks-animation-flutter-animation-sequences/) \] \[ [Video](https://youtu.be/mdhoIQqS2z0) \] - This tutorial goes over every way you can organise your animation code using the provided flutter functionality. Then we go to Flutter hooks to help reduce the code and we look at the sequence builder to create some combined animations. - -**018 - Bottom Sheet Guide in Flutter** \[ [Written](https://www.filledstacks.com/post/bottom-sheet-guide-in-flutter) \] \[ [Video](https://youtu.be/zXFcceP0JbY) \] - This tutorial goes over everything you need to know to effectively make use of the BottomSheet in your app. - -**017 - Better Logging in Flutter** \[ [Written - Effective Logging](https://www.filledstacks.com/post/flutter-logging-a-guide-to-use-it-effectively) \] \[ [Written - Setup Guide](https://www.filledstacks.com/snippet/a-guide-to-setting-up-better-logging-in-flutter) \] \[ [Video](https://youtu.be/c5CwHXj21xw) \] - This set of tutorials cover logging in Flutter. It shows you how to set it up, and it also gives you guidelines on where to use it and what to log when using it. - -**016 - Flutter Navigation using Named Routing** \[ [Written](https://www.filledstacks.com/post/flutter-navigation-cheatsheet-a-guide-to-named-routing) \] \[ [Video](https://youtu.be/YXDFlpdpp3g) \] - This tutorial guides you through everything you need to know about navigation in Flutter using named routing. - -**015 - Animated SplashScreen with Flare** \[ [Written](https://www.filledstacks.com/post/flutter-animated-splash-screen-with-flare) \] \[ [Video](https://youtu.be/4PgdFYcQpuc) \] - This tutorial shows how to setup your splash following up with a nice intro animation built in Flare. - -**014 - Flutter Provider V3 Architecture using ProxyProvider** \[ [Written](https://www.filledstacks.com/post/flutter-provider-v3-architecture) \] \[ [Video](https://youtu.be/VgrK_LlQRJ4) \] - In this tutorial we implement a previously built app using Provider only and show how an architecture with dependency injection can be setup using the ProxyProvider. - -**013 - Flutter Dependency Injection for Beginners** \[ [Written](https://www.filledstacks.com/post/flutter-dependency-injection-a-beginners-guide/) \] \[ [Video](https://youtu.be/vBT-FhgMaWM) \] - In this tutorial I explain what dependency injection is in plain english and show three ways of implementing it in Flutter. - -**012 - Flutter Provider - Sharing Data Between Models using Services** \[ [Written](https://www.filledstacks.com/post/flutter-provider-architecture-sharing-data-across-your-models/) \] \[ [Video](https://youtu.be/dnW0NunWBTM) \] - In this tutorial I expand on my previous tutorial showing how you share data between models using services. - -**011 - Network Sensitive UI in Flutter using Provider and Connectivity** \[ [Written](https://www.filledstacks.com/post/make-your-flutter-app-network-aware-using-provider-and-connectivity-status/) \] \[ [Video](https://youtu.be/u9O8NOnQi_A) \] - In this tutorial I create a network sensitive UI that shows different states based on the status of your connection. - -**010 - Flutter Architecture - A complete guide to Provider** \[ [Written](https://www.filledstacks.com/post/flutter-architecture-my-provider-implementation-guide) \] \[ [Video](https://youtu.be/kDEflMYTFlk) \] - In this tutorial / guide I cover the complete architecture to build a production app using the provider package for state management. - -**009 - Build a User Feedback app using Flutter and Firebase** \[ [Written](https://www.filledstacks.com/post/build-a-user-feedback-app-in-flutter-and-firebase) \] \[ [Video](https://youtu.be/g5-ZkfN2mvY) \] - In this tutorial I guide you through the steps to implement a real time user feedback app using firebase, flutter and the ScopedModel architecture. - -**008 - Building a Realtime stats monitor using Flutter and Firebase** \[ [Written](https://www.filledstacks.com/post/building-a-realtime-stats-monitor-in-flutter) \] \[ [Video](https://youtu.be/qa6A2TOqY0A) \] - In this tutorial I go over the steps for implementing a real time stats monitor for [AppSkeletons](https://www.appskeletons.com/) - -**007 - Flutter Architecture - A complete guide to the ScopedModel architecture** \[ [Written](https://www.filledstacks.com/post/flutter-architecture-scoped-model-implementation-guide) \] \[ [Video](https://youtu.be/JsjDLHxGz4M) \] \[ [AppSkeletons](https://www.appskeletons.com/) \]- In this tutorial we'll lay the foundation to develop an application using Flutter and ScopedModel that's easy to maintain and extend. - -**006 - Flutter + (Smart)Flare - Building a Gooey side menu** \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/006-flare-drawer) \] \[ [Video](https://youtu.be/fZuLh-oc5Ao) \] \[ [Animation](https://www.2dimensions.com/a/danemackier/files/flare/slideout-menu/preview) \] \[ [Written (code only)](https://www.filledstacks.com/post/flare-and-flutter-build-a-super-cool-gooey-slideout-menu) \] - In this tutorial I go over the process of building a slide out menu in Flare. Then importing into Flutter and using SmartFlare to add some interactive functionality to it. - -**005 - Overflown Stacks - A Guide to basic navigation in Flutter using Navigator** \[ [Video](https://youtu.be/DlArCl8jvlo) \] \[ [Written](https://www.filledstacks.com/post/flutter-navigation-cheatsheet-a-guide-to-the-navigator) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/005-basic-navigation) \] - This repo contains an implementation of basic navigation using the code snippets defined in the guide. - -**004 - Flutter Foundation - Handling Async behaviour - From setState to Architecture** \[ [Written](https://www.filledstacks.com/post/flutter-basics-going-from-set-state-to-architecture) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/004-flutter-basics) \] \[ [Video](https://youtu.be/TZkGT8WkjdA) \] - In this tutorial I show how you to handle async functionality and all it's states starting with setState and working up to a reactive architecture using streams. - -**003 - Using SmartFlare for Flare animation interactions** \[ [Video](https://youtu.be/vsyjMrZa5OU) \] \[ [Written](https://www.filledstacks.com/post/smart-flare-interactive-flare-actors-in-flutter-an-experiment) \] \[ [Package](https://github.com/FilledStacks/smart_flare) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/003-smart-flare) \] - In this tutorial I introduce my SmartFlare package that wraps normal FlareActors into a more interactable widget. - -**002 - Smarter Flare Animations in Flutter - An Experiment** \[ [Video](https://youtu.be/vsyjMrZa5OU) \] \[ [Written](https://www.filledstacks.com/post/reducing-boilerplate-code-in-flutter-using-flare) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/002-flutter-flare-pt1) \] - In this tutorial we look at how to reduce animation boiler plate code in Flutter using some basic calculations and the Awesome Flare. - -**001 - Building a UI in Flutter - TikTok example:** \[ [Video](https://youtu.be/kJ2mGh5BLYk) \] \[ [Written P1](https://www.filledstacks.com/post/building-tik-tok-s-ui-in-flutter-the-building-process) \] \[[Written P2](https://www.filledstacks.com/post/building-tik-tok-s-ui-in-flutter-from-layout-to-polish)\] \[[Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/001-tik_tok_ui)\] - In this tutorial we break down the UI into Flutter Widgets, complete our layout and then tweak to get our final design to match our screenshots. +# Flutter tutorials +The repo contains the source code for all the written tutorials by Filledstacks. + +All Tutorials plus additional snippets and shorter posts can be found on the [Official FilledStacks website](https://www.filledstacks.com/). + +Please clone and star this repo to stay up to date on changes. + +## Turorials + +**011 - Network Sensitive UI in Flutter using Provider and Connectivity** \[ [Written](https://www.filledstacks.com/post/make-your-flutter-app-network-aware-using-provider-and-connectivity-status/) \] \[ [Video](https://youtu.be/u9O8NOnQi_A) \] - In this tutorial I create a network sensitive UI that shows different states based on the status of your connection. + +**010 - Flutter Architecture - A complete guide to Provider** \[ [Written](https://www.filledstacks.com/post/flutter-architecture-my-provider-implementation-guide) \] \[ [Video](https://youtu.be/kDEflMYTFlk) \] - In this tutorial / guide I cover the complete architecture to build a production app using the provider package for state management. + +**009 - Build a User Feedback app using Flutter and Firebase** \[ [Written](https://www.filledstacks.com/post/build-a-user-feedback-app-in-flutter-and-firebase) \] \[ [Video](https://youtu.be/g5-ZkfN2mvY) \] - In this tutorial I guide you through the steps to implement a real time user feedback app using firebase, flutter and the ScopedModel architecture. + +**008 - Building a Realtime stats monitor using Flutter and Firebase** \[ [Written](https://www.filledstacks.com/post/building-a-realtime-stats-monitor-in-flutter) \] \[ [Video](https://youtu.be/qa6A2TOqY0A) \] - In this tutorial I go over the steps for implementing a real time stats monitor for [AppSkeletons](https://www.appskeletons.com/) + +**007 - Flutter Architecture - A complete guide to the ScopedModel architecture** \[ [Written](https://www.filledstacks.com/post/flutter-architecture-scoped-model-implementation-guide) \] \[ [Video](https://youtu.be/JsjDLHxGz4M) \] \[ [AppSkeletons](https://www.appskeletons.com/) \]- In this tutorial we'll lay the foundation to develop an application using Flutter and ScopedModel that's easy to maintain and extend. + +**006 - Flutter + (Smart)Flare - Building a Gooey side menu** \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/006-flare-drawer) \] \[ [Video](https://youtu.be/fZuLh-oc5Ao) \] \[ [Animation](https://www.2dimensions.com/a/danemackier/files/flare/slideout-menu/preview) \] \[ [Written (code only)](https://www.filledstacks.com/post/flare-and-flutter-build-a-super-cool-gooey-slideout-menu) \] - In this tutorial I go over the process of building a slideout menu in Flare. Then importing into Flutter and using SmartFlare to add some interactive functionality to it. + +**005 - Overflown Stacks - A Guide to basic navigation in Flutter using Navigator** \[ [Video](https://youtu.be/DlArCl8jvlo) \] \[ [Written](https://www.filledstacks.com/post/flutter-navigation-cheatsheet-a-guide-to-the-navigator) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/005-basic-navigation) \] - This repo contains an implementation of basic navigation using the code snippets defined in the guide. + +**004 - Flutter Foundation - Handling Async behaviour - From setState to Architecture** \[ [Written](https://www.filledstacks.com/post/flutter-basics-going-from-set-state-to-architecture) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/004-flutter-basics) \] \[ [Video](https://youtu.be/TZkGT8WkjdA) \] - In this tutorial I show how you to handle async functionality and all it's states starting with setState and working up to a reactive architecture using streams. + +**003 - Using SmartFlare for Flare animation interactions** \[ [Video](https://youtu.be/vsyjMrZa5OU) \] \[ [Written](https://www.filledstacks.com/post/smart-flare-interactive-flare-actors-in-flutter-an-experiment) \] \[ [Package](https://github.com/FilledStacks/smart_flare) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/003-smart-flare) \] - In this tutorial I introduce my SmartFlare package that wraps normal FlareActors into a more interactable widget. + +**002 - Smarter Flare Animations in Flutter - An Experiment** \[ [Video](https://youtu.be/vsyjMrZa5OU) \] \[ [Written](https://www.filledstacks.com/post/reducing-boilerplate-code-in-flutter-using-flare) \] \[ [Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/002-flutter-flare-pt1) \] - In this tutorial we look at how to reduce animation boiler plate code in Flutter using some basic calculations and the Awesome Flare. + +**001 - Building a UI in Flutter - TikTok example:** \[ [Video](https://youtu.be/kJ2mGh5BLYk) \] \[ [Written P1](https://www.filledstacks.com/post/building-tik-tok-s-ui-in-flutter-the-building-process) \] \[[Written P2](https://www.filledstacks.com/post/building-tik-tok-s-ui-in-flutter-from-layout-to-polish)\] \[[Source](https://github.com/FilledStacks/flutter-tutorials/tree/master/tik_tok_ui)\] - In this tutorial we break down the UI into Flutter Widgets, complete our layout and then tweak to get our final design to match our screenshots. + + +## Tools by FilledStacks + +[AppSkeletons](https://www.appskeletons.com/): Create your own custom template, perfectly architected and catered to your scenario. Add predefined view types and skip 2-3 days of code setup and just start developing + +[SmartFlare](https://pub.dartlang.org/packages/smart_flare): An extension of the already awesome Flare packages that adds interactive to FlareActors with some more functionality.