├── .git-crypt
├── .gitattributes
└── keys
│ └── default
│ └── 0
│ └── E2236A7EAE7C97C0E7E1123D54BA00035D9A09E2.gpg
├── .gitattributes.txt
├── .github
└── workflows
│ └── github_action.yml
├── .gitignore
├── .gradle
├── 5.2.1
│ ├── fileChanges
│ │ └── last-build.bin
│ ├── fileHashes
│ │ └── fileHashes.lock
│ └── gc.properties
├── buildOutputCleanup
│ ├── buildOutputCleanup.lock
│ └── cache.properties
└── vcs-1
│ └── gc.properties
├── .metadata
├── LICENSE
├── README.md
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ ├── google-services.json
│ ├── libs
│ │ └── jsch-0.1.55.jar
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── aajinkya
│ │ │ │ └── sign_in
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── SshPlugin.java
│ │ └── res
│ │ │ ├── drawable
│ │ │ └── launch_background.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ └── styles.xml
│ │ └── profile
│ │ └── AndroidManifest.xml
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ └── gradle-wrapper.properties
└── settings.gradle
├── assets
├── Aajinkya.jpg
├── About2.png
├── Aditi.png
├── Calibre Semibold.otf
├── Flower_Float.txt
├── Home2.png
├── Miheer.png
├── Pratit.png
├── Reports.gif
├── RoverDev0.jpg
├── RoverDev1.jpg
├── RoverDev2.jpg
├── RoverDev3.jpg
├── RoverPy App.jpg
├── RoverPy_Logo.png
├── SF-Pro-Text-Bold.otf
├── SF-Pro-Text-Regular.otf
├── Sponsor2.png
├── Teddy.flr
├── TomatoModel.txt
├── WhatsNew.png
├── about.gif
├── aboutUs.png
├── background.flr
├── controller.jpg
├── custom_icons.ttf
├── dict.txt
├── github_logo.png
├── image_01.png
├── image_02.jpg
├── image_03.jpg
├── image_04.jpg
├── loadingSpaceman.flr
├── locate.jpg
├── manifest.json
├── map.gif
├── map.jpg
├── model.tflite
├── model_unquant.tflite
├── person.png
├── preview.png
├── profileCard.jpg
├── success.flr
├── test_barcode.jpg
├── test_face.jpg
├── test_text.png
└── user.gif
├── demo
├── RoverPyHomePage.mp4
├── RoverPyIOSUI.mp4
├── RoverPyProfile.mp4
└── RoverPyWorkingRover.mp4
├── fonts
├── LexendDeca-Regular.ttf
├── Poppins-Medium.ttf
└── Raleway-SemiBold.ttf
├── ios
├── .gitignore
├── Flutter
│ ├── AppFrameworkInfo.plist
│ ├── Debug.xcconfig
│ └── Release.xcconfig
├── Podfile
├── Runner.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── IDEWorkspaceChecks.plist
│ │ │ └── WorkspaceSettings.xcsettings
│ └── xcshareddata
│ │ └── xcschemes
│ │ └── Runner.xcscheme
├── Runner.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── Runner
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ ├── Contents.json
│ │ ├── Icon-App-1024x1024@1x.png
│ │ ├── Icon-App-20x20@1x.png
│ │ ├── Icon-App-20x20@2x.png
│ │ ├── Icon-App-20x20@3x.png
│ │ ├── Icon-App-29x29@1x.png
│ │ ├── Icon-App-29x29@2x.png
│ │ ├── Icon-App-29x29@3x.png
│ │ ├── Icon-App-40x40@1x.png
│ │ ├── Icon-App-40x40@2x.png
│ │ ├── Icon-App-40x40@3x.png
│ │ ├── Icon-App-60x60@2x.png
│ │ ├── Icon-App-60x60@3x.png
│ │ ├── Icon-App-76x76@1x.png
│ │ ├── Icon-App-76x76@2x.png
│ │ └── Icon-App-83.5x83.5@2x.png
│ └── LaunchImage.imageset
│ │ ├── Contents.json
│ │ ├── LaunchImage.png
│ │ ├── LaunchImage@2x.png
│ │ ├── LaunchImage@3x.png
│ │ └── README.md
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Info.plist
│ └── main.m
├── lib
├── animations.dart
├── auth
│ ├── constants.dart
│ ├── login.dart
│ └── register.dart
├── commons
│ ├── animated_popup.dart
│ ├── collapsing_navigation_drawer.dart
│ ├── custom_card.dart
│ ├── drawer_tile.dart
│ └── stepper_control.dart
├── helpers
│ ├── map_helper.dart
│ └── map_marker.dart
├── main.dart
├── models
│ ├── developer_info.dart
│ ├── drawer_item.dart
│ ├── models_export.dart
│ ├── series_model.dart
│ ├── theme_model.dart
│ └── user.dart
├── pages
│ ├── QuickAccess.dart
│ ├── Specific.dart
│ ├── about.dart
│ ├── constants_profile.dart
│ ├── controls_page.dart
│ ├── home_page.dart
│ ├── map_page.dart
│ ├── new_process_page.dart
│ ├── pages_export.dart
│ ├── process_page.dart
│ ├── profile.dart
│ ├── report_page.dart
│ ├── shh_page.dart
│ ├── ssh.dart
│ ├── tf.dart
│ └── video_page.dart
├── services
│ ├── AuthService.dart
│ ├── BackgroundCollectedPage.dart
│ ├── BackgroundCollectingTask.dart
│ ├── BluetoothDeviceListEntry.dart
│ ├── ChatPage.dart
│ ├── DiscoveryPage.dart
│ ├── MainPage.dart
│ ├── SelectBondedDevicePage.dart
│ ├── bluetoothSerial.dart
│ └── helpers
│ │ ├── LineChart.dart
│ │ └── PaintStyle.dart
├── utils
│ ├── customIcons.dart
│ ├── data.dart
│ ├── themes.dart
│ └── utils_export.dart
└── wrapper.dart
├── pubspec.lock
├── pubspec.yaml
└── test
└── widget_test.dart
/.git-crypt/.gitattributes:
--------------------------------------------------------------------------------
1 | # Do not edit this file. To specify the files to encrypt, create your own
2 | # .gitattributes file in the directory where your files are.
3 | * !filter !diff
4 | *.gpg binary
--------------------------------------------------------------------------------
/.git-crypt/keys/default/0/E2236A7EAE7C97C0E7E1123D54BA00035D9A09E2.gpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/.git-crypt/keys/default/0/E2236A7EAE7C97C0E7E1123D54BA00035D9A09E2.gpg
--------------------------------------------------------------------------------
/.gitattributes.txt:
--------------------------------------------------------------------------------
1 | google-services.json filter=git-crypt diff=git-crypt
--------------------------------------------------------------------------------
/.github/workflows/github_action.yml:
--------------------------------------------------------------------------------
1 | name: Build CI
2 | on: [push, pull_request_target]
3 |
4 | jobs:
5 | build:
6 | name: Build for Android
7 | runs-on: ubuntu-latest
8 |
9 | steps:
10 | - name: Clone repository
11 | uses: actions/checkout@v2
12 |
13 | - name: Setup Java
14 | uses: actions/setup-java@v1
15 | with:
16 | java-version: '12.x'
17 |
18 | - name: Setup Flutter
19 | uses: subosito/flutter-action@v1
20 |
21 | - name: Build APK
22 | run: |
23 | flutter pub get
24 | flutter build apk
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .flutter-plugins-dependencies
28 | .packages
29 | .pub-cache/
30 | .pub/
31 | /build/
32 |
33 | # Web related
34 | lib/generated_plugin_registrant.dart
35 |
36 | # Symbolication related
37 | app.*.symbols
38 |
39 | # Obfuscation related
40 | app.*.map.json
41 |
42 | # Exceptions to above rules.
43 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
44 |
--------------------------------------------------------------------------------
/.gradle/5.2.1/fileChanges/last-build.bin:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gradle/5.2.1/fileHashes/fileHashes.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/.gradle/5.2.1/fileHashes/fileHashes.lock
--------------------------------------------------------------------------------
/.gradle/5.2.1/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/.gradle/5.2.1/gc.properties
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/buildOutputCleanup.lock:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/.gradle/buildOutputCleanup/buildOutputCleanup.lock
--------------------------------------------------------------------------------
/.gradle/buildOutputCleanup/cache.properties:
--------------------------------------------------------------------------------
1 | #Sun Jul 12 20:57:57 IST 2020
2 | gradle.version=5.2.1
3 |
--------------------------------------------------------------------------------
/.gradle/vcs-1/gc.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/.gradle/vcs-1/gc.properties
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: 8af6b2f038c1172e61d418869363a28dffec3cb4
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Aajinkya Singh
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # RoverPy App
6 | > Taking Agriculture to a whole new level!
7 |
8 | This is an application interface for the [RoverPy Project](https://github.com/RoverPy/RoverPy), which allows the farmers to see whatever is going on their RoverPy on the app.
9 |
10 | The job of the app is to process the images captured by the RoverPy using a Tensorflow Lite Model deployed on Firebase Custom Model, while at the same time control the RoverPy from the Controls Page and see a live-feed on the app. Wait that's not it, our app provides an interface to see all the past records of the RoverPy's round and depending on the confidence level (of it's health) a bar-chart is built in realtime to give a graphical representation of all the past records! Moreover, to actually visualize where the plant was detected we have provided marker's (either healthy / unhealthy) on Google Map using the co-ordinates gathered by the RoverPy.
11 |
12 | ## Key Features
13 | - [x] Our custom Tensorflow Lite Model is being used on our App
14 | - [x] Our own Dataset gathered from a live farm
15 | - [x] Multiple Tensorflow Models for various plants & flowers to detect a wide array of diseases
16 | - [x] Live feed directly from the RoverPy to our app
17 | - [x] Controlling the RoverPy from our App
18 | - [x] An in-depth stastical insight for the past records
19 | - [x] Use of dynamic graphs based on the confidence level
20 | - [x] A minimalistic yet sexy UI :wink:
21 |
22 | ## Screenshots
23 |
24 |
25 |
26 |
27 | ## Contributors
28 | This project was made by:
29 | - [Pratit Bandiwadekar](https://github.com/Pratit23)
30 | - [Aajinkya Singh](https://github.com/aajinkya1203)
31 | - [Aditi Mohan](https://github.com/Aditi-Mohan)
32 | - [Miheer Thampi](https://github.com/mimi69-38)
33 |
34 | ## Found something off? Want to collaborate?
35 | - Fork this repo
36 | - Make your changes
37 | - Make a PR and add any of the [Contributor](https://github.com/RoverPy/RoverPyApp#contributors) above as a [Reviewer](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/requesting-a-pull-request-review)
38 |
39 | ## License
40 | You can view our License [here](https://github.com/RoverPy/RoverPyApp/blob/master/LICENSE)
41 |
--------------------------------------------------------------------------------
/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
--------------------------------------------------------------------------------
/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'com.google.gms.google-services'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 |
29 | android {
30 | compileSdkVersion 28
31 |
32 | aaptOptions {
33 | noCompress "tflite"
34 | noCompress 'lite'
35 | }
36 |
37 | lintOptions {
38 | disable 'InvalidPackage'
39 | }
40 |
41 | defaultConfig {
42 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
43 | applicationId "aajinkya.sign_in"
44 | minSdkVersion 23
45 | targetSdkVersion 28
46 | versionCode flutterVersionCode.toInteger()
47 | versionName flutterVersionName
48 | multiDexEnabled true
49 | }
50 |
51 | buildTypes {
52 | release {
53 | // TODO: Add your own signing config for the release build.
54 | // Signing with the debug keys for now, so `flutter run --release` works.
55 | signingConfig signingConfigs.debug
56 | }
57 | }
58 | }
59 |
60 | flutter {
61 | source '../..'
62 | }
63 |
64 | dependencies {
65 | // ...
66 | // Image labeling feature with automl model downloaded
67 | // from firebase
68 | implementation 'com.google.mlkit:image-labeling-automl:16.0.0'
69 | implementation 'com.google.mlkit:linkfirebase:16.0.0'
70 | testImplementation 'junit:junit:4.12'
71 | androidTestImplementation 'androidx.test:runner:1.1.1'
72 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
73 | implementation 'org.tensorflow:tensorflow-lite:2.0.0'
74 | implementation files('libs/jsch-0.1.55.jar')
75 | }
--------------------------------------------------------------------------------
/android/app/google-services.json:
--------------------------------------------------------------------------------
1 | {
2 | "project_info": {
3 | "project_number": "202297952467",
4 | "firebase_url": "https://roverpy-aamp.firebaseio.com",
5 | "project_id": "roverpy-aamp",
6 | "storage_bucket": "roverpy-aamp.appspot.com"
7 | },
8 | "client": [
9 | {
10 | "client_info": {
11 | "mobilesdk_app_id": "1:202297952467:android:e6318e1afa9d298c352c26",
12 | "android_client_info": {
13 | "package_name": "aajinkya.sign_in"
14 | }
15 | },
16 | "oauth_client": [
17 | {
18 | "client_id": "202297952467-so23djdglh979c803vnt77i4gutrdrg5.apps.googleusercontent.com",
19 | "client_type": 3
20 | }
21 | ],
22 | "api_key": [
23 | {
24 | "current_key": "AIzaSyBK_rUshb6zhCrR7tEKjGMuDuT2yDXRfMc"
25 | }
26 | ],
27 | "services": {
28 | "appinvite_service": {
29 | "other_platform_oauth_client": [
30 | {
31 | "client_id": "202297952467-so23djdglh979c803vnt77i4gutrdrg5.apps.googleusercontent.com",
32 | "client_type": 3
33 | }
34 | ]
35 | }
36 | }
37 | }
38 | ],
39 | "configuration_version": "1"
40 | }
--------------------------------------------------------------------------------
/android/app/libs/jsch-0.1.55.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/android/app/libs/jsch-0.1.55.jar
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
8 |
9 |
10 |
11 |
16 |
17 |
19 |
26 |
30 |
34 |
39 |
43 |
44 |
45 |
46 |
47 |
48 |
50 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/android/app/src/main/java/aajinkya/sign_in/MainActivity.java:
--------------------------------------------------------------------------------
1 | package aajinkya.sign_in;
2 |
3 | import io.flutter.embedding.android.FlutterActivity;
4 |
5 | public class MainActivity extends FlutterActivity {
6 | }
7 |
--------------------------------------------------------------------------------
/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | google()
4 | jcenter()
5 | maven {
6 | url 'https://google.bintray.com/exoplayer/'
7 | }
8 | }
9 |
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.5.0'
12 | classpath 'com.google.gms:google-services:4.0.1'
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | google()
19 | jcenter()
20 | }
21 | }
22 |
23 | rootProject.buildDir = '../build'
24 | subprojects {
25 | project.buildDir = "${rootProject.buildDir}/${project.name}"
26 | }
27 | subprojects {
28 | project.evaluationDependsOn(':app')
29 | }
30 |
31 | task clean(type: Delete) {
32 | delete rootProject.buildDir
33 | }
34 |
--------------------------------------------------------------------------------
/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.enableR8=true
3 | android.useAndroidX=true
4 | android.enableJetifier=true
5 |
--------------------------------------------------------------------------------
/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jun 23 08:50:38 CEST 2017
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
7 |
--------------------------------------------------------------------------------
/android/settings.gradle:
--------------------------------------------------------------------------------
1 | // Copyright 2014 The Flutter Authors. All rights reserved.
2 | // Use of this source code is governed by a BSD-style license that can be
3 | // found in the LICENSE file.
4 |
5 | include ':app'
6 |
7 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
8 | def properties = new Properties()
9 |
10 | assert localPropertiesFile.exists()
11 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
12 |
13 | def flutterSdkPath = properties.getProperty("flutter.sdk")
14 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
15 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
16 |
17 |
18 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath()
19 |
20 | def plugins = new Properties()
21 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins')
22 | if (pluginsFile.exists()) {
23 | pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) }
24 | }
25 |
26 | plugins.each { name, path ->
27 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile()
28 | include ":$name"
29 | project(":$name").projectDir = pluginDirectory
30 | }
--------------------------------------------------------------------------------
/assets/Aajinkya.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Aajinkya.jpg
--------------------------------------------------------------------------------
/assets/About2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/About2.png
--------------------------------------------------------------------------------
/assets/Aditi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Aditi.png
--------------------------------------------------------------------------------
/assets/Calibre Semibold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Calibre Semibold.otf
--------------------------------------------------------------------------------
/assets/Flower_Float.txt:
--------------------------------------------------------------------------------
1 | 0 Daisy
2 | 1 Dandelion
3 | 2 Roses
4 | 3 Sunflower
5 | 4 Tulips
6 |
--------------------------------------------------------------------------------
/assets/Home2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Home2.png
--------------------------------------------------------------------------------
/assets/Miheer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Miheer.png
--------------------------------------------------------------------------------
/assets/Pratit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Pratit.png
--------------------------------------------------------------------------------
/assets/Reports.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Reports.gif
--------------------------------------------------------------------------------
/assets/RoverDev0.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/RoverDev0.jpg
--------------------------------------------------------------------------------
/assets/RoverDev1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/RoverDev1.jpg
--------------------------------------------------------------------------------
/assets/RoverDev2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/RoverDev2.jpg
--------------------------------------------------------------------------------
/assets/RoverDev3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/RoverDev3.jpg
--------------------------------------------------------------------------------
/assets/RoverPy App.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/RoverPy App.jpg
--------------------------------------------------------------------------------
/assets/RoverPy_Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/RoverPy_Logo.png
--------------------------------------------------------------------------------
/assets/SF-Pro-Text-Bold.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/SF-Pro-Text-Bold.otf
--------------------------------------------------------------------------------
/assets/SF-Pro-Text-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/SF-Pro-Text-Regular.otf
--------------------------------------------------------------------------------
/assets/Sponsor2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Sponsor2.png
--------------------------------------------------------------------------------
/assets/Teddy.flr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/Teddy.flr
--------------------------------------------------------------------------------
/assets/TomatoModel.txt:
--------------------------------------------------------------------------------
1 | 0 healthy
2 | 1 early_blight
3 |
--------------------------------------------------------------------------------
/assets/WhatsNew.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/WhatsNew.png
--------------------------------------------------------------------------------
/assets/about.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/about.gif
--------------------------------------------------------------------------------
/assets/aboutUs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/aboutUs.png
--------------------------------------------------------------------------------
/assets/background.flr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/background.flr
--------------------------------------------------------------------------------
/assets/controller.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/controller.jpg
--------------------------------------------------------------------------------
/assets/custom_icons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/custom_icons.ttf
--------------------------------------------------------------------------------
/assets/dict.txt:
--------------------------------------------------------------------------------
1 | Apple___Black_rot
2 | Apple___healthy
3 |
--------------------------------------------------------------------------------
/assets/github_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/github_logo.png
--------------------------------------------------------------------------------
/assets/image_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/image_01.png
--------------------------------------------------------------------------------
/assets/image_02.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/image_02.jpg
--------------------------------------------------------------------------------
/assets/image_03.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/image_03.jpg
--------------------------------------------------------------------------------
/assets/image_04.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/image_04.jpg
--------------------------------------------------------------------------------
/assets/loadingSpaceman.flr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/loadingSpaceman.flr
--------------------------------------------------------------------------------
/assets/locate.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/locate.jpg
--------------------------------------------------------------------------------
/assets/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "modelFile": "model.tflite",
3 | "labelsFile": "dict.txt",
4 | "modelType": "IMAGE_LABELING"
5 | }
--------------------------------------------------------------------------------
/assets/map.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/map.gif
--------------------------------------------------------------------------------
/assets/map.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/map.jpg
--------------------------------------------------------------------------------
/assets/model.tflite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/model.tflite
--------------------------------------------------------------------------------
/assets/model_unquant.tflite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/model_unquant.tflite
--------------------------------------------------------------------------------
/assets/person.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/person.png
--------------------------------------------------------------------------------
/assets/preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/preview.png
--------------------------------------------------------------------------------
/assets/profileCard.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/profileCard.jpg
--------------------------------------------------------------------------------
/assets/success.flr:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/success.flr
--------------------------------------------------------------------------------
/assets/test_barcode.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/test_barcode.jpg
--------------------------------------------------------------------------------
/assets/test_face.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/test_face.jpg
--------------------------------------------------------------------------------
/assets/test_text.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/test_text.png
--------------------------------------------------------------------------------
/assets/user.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/assets/user.gif
--------------------------------------------------------------------------------
/demo/RoverPyHomePage.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/demo/RoverPyHomePage.mp4
--------------------------------------------------------------------------------
/demo/RoverPyIOSUI.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/demo/RoverPyIOSUI.mp4
--------------------------------------------------------------------------------
/demo/RoverPyProfile.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/demo/RoverPyProfile.mp4
--------------------------------------------------------------------------------
/demo/RoverPyWorkingRover.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/demo/RoverPyWorkingRover.mp4
--------------------------------------------------------------------------------
/fonts/LexendDeca-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/fonts/LexendDeca-Regular.ttf
--------------------------------------------------------------------------------
/fonts/Poppins-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/fonts/Poppins-Medium.ttf
--------------------------------------------------------------------------------
/fonts/Raleway-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/fonts/Raleway-SemiBold.ttf
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 8.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
32 | end
33 |
34 | post_install do |installer|
35 | installer.pods_project.targets.each do |target|
36 | flutter_additional_ios_build_settings(target)
37 | end
38 | end
39 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
4 | @interface AppDelegate : FlutterAppDelegate
5 |
6 | @end
7 |
--------------------------------------------------------------------------------
/ios/Runner/AppDelegate.m:
--------------------------------------------------------------------------------
1 | #import "AppDelegate.h"
2 | #import "GeneratedPluginRegistrant.h"
3 |
4 | @implementation AppDelegate
5 |
6 | - (BOOL)application:(UIApplication *)application
7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
8 | [GeneratedPluginRegistrant registerWithRegistry:self];
9 | // Override point for customization after application launch.
10 | return [super application:application didFinishLaunchingWithOptions:launchOptions];
11 | }
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RoverPy/RoverPyApp/e39abf68aa9a7ed339963daeb5ef937431b9e30b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | 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.
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | sign_in
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/ios/Runner/main.m:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 | #import "AppDelegate.h"
4 |
5 | int main(int argc, char* argv[]) {
6 | @autoreleasepool {
7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/animations.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/foundation.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flare_flutter/flare_actor.dart';
4 | import 'package:sign_in/auth/login.dart';
5 | import 'package:sign_in/auth/register.dart';
6 |
7 | class AuthDemo extends StatefulWidget {
8 | @override
9 | _AuthDemoState createState() => _AuthDemoState();
10 | }
11 |
12 | class _AuthDemoState extends State
13 | with SingleTickerProviderStateMixin {
14 | String _animationName = "Flow";
15 | Animation classificationAnimation;
16 | AnimationController controller;
17 | bool controly = false;
18 | void toggleView() {
19 | setState(() {
20 | controly = !controly;
21 | });
22 | }
23 |
24 | @override
25 | void dispose() {
26 | assert(() {
27 | if (controller == null) {
28 | throw FlutterError.fromParts([
29 | ErrorSummary('AnimationController.dispose() called more than once.'),
30 | ]);
31 | }
32 | return true;
33 | }());
34 | controller.dispose();
35 | controller = null;
36 | super.dispose();
37 | }
38 |
39 | Widget showWidget() {
40 | controller.forward();
41 | return controly
42 | ? SlideTransition(
43 | position: classificationAnimation,
44 | child: (Container(
45 | alignment: Alignment.center,
46 | child: LoginScreen(
47 | toggleView: toggleView,
48 | controller: dispose,
49 | ),
50 | )),
51 | )
52 | : SlideTransition(
53 | position: classificationAnimation,
54 | child: (Container(
55 | alignment: Alignment.center,
56 | child: Register(toggleView: toggleView, controller: dispose),
57 | )),
58 | );
59 | }
60 |
61 | @override
62 | void initState() {
63 | super.initState();
64 | controller = AnimationController(
65 | duration: Duration(milliseconds: 3000), vsync: this);
66 | classificationAnimation = Tween(
67 | begin: Offset(6.0, 0.0),
68 | end: Offset.zero,
69 | ).animate(
70 | CurvedAnimation(
71 | parent: controller,
72 | curve: Interval(
73 | 0.5,
74 | 0.7,
75 | curve: Curves.easeOut,
76 | ),
77 | ),
78 | );
79 | }
80 |
81 | @override
82 | Widget build(BuildContext context) {
83 | controller.forward();
84 | return Scaffold(
85 | body: Stack(
86 | fit: StackFit.expand,
87 | children: [
88 | FlareActor(
89 | 'assets/background.flr',
90 | alignment: Alignment.topCenter,
91 | fit: BoxFit.cover,
92 | animation: _animationName,
93 | callback: (String val) {
94 | setState(() {
95 | _animationName = "Flow";
96 | });
97 | },
98 | ),
99 | showWidget(),
100 | ],
101 | overflow: Overflow.clip,
102 | ),
103 | );
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/lib/auth/constants.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | dynamic textInputDecoration = InputDecoration(
5 | hintStyle: TextStyle(
6 | fontFamily: 'Lexend_Deca',
7 | ),
8 | filled: true,
9 | fillColor: Colors.grey[100],
10 | enabledBorder: OutlineInputBorder(
11 | borderSide: BorderSide.none,
12 | borderRadius: BorderRadius.all(
13 | const Radius.circular(50.0),
14 | ),
15 | ),
16 | focusedBorder: OutlineInputBorder(
17 | borderSide: BorderSide(color: Colors.deepPurple, width: 2.0),
18 | borderRadius: BorderRadius.all(
19 | const Radius.circular(50.0),
20 | ),
21 | ),
22 |
23 | );
--------------------------------------------------------------------------------
/lib/auth/login.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/widgets.dart';
3 | import 'package:sign_in/auth/constants.dart';
4 | import 'package:sign_in/models/user.dart';
5 | import 'package:sign_in/services/AuthService.dart';
6 |
7 | class LoginScreen extends StatefulWidget {
8 | final Function toggleView, controller;
9 | LoginScreen({this.toggleView, this.controller});
10 | @override
11 | _LoginScreenState createState() => _LoginScreenState();
12 | }
13 |
14 | class _LoginScreenState extends State {
15 | final AuthService _auth = AuthService();
16 | final _formKey = GlobalKey();
17 | String email = "";
18 | String password = "";
19 | String name = "";
20 |
21 | @override
22 | Widget build(BuildContext context) {
23 | return Container(
24 | padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 20.0),
25 | height: 500,
26 | child: Card(
27 | elevation: 8,
28 | shape: RoundedRectangleBorder(
29 | borderRadius: BorderRadius.circular(20.0),
30 | ),
31 | child: Form(
32 | key: _formKey,
33 | child: Padding(
34 | padding: const EdgeInsets.all(20.0),
35 | child: Column(
36 | mainAxisAlignment: MainAxisAlignment.spaceAround,
37 | children: [
38 | SizedBox(
39 | height: 10.0,
40 | ),
41 | Row(
42 | children: [
43 | Text(
44 | "RoverPy",
45 | style: TextStyle(
46 | fontSize: 30.0,
47 | color: Colors.amber,
48 | fontWeight: FontWeight.bold,
49 | letterSpacing: .6,
50 | ),
51 | ),
52 | ],
53 | ),
54 |
55 | TextFormField(
56 | decoration: textInputDecoration.copyWith(
57 | prefixIcon: Icon(Icons.supervised_user_circle), hintText: "Display Name"),
58 | validator: (val) {
59 | return null;
60 | },
61 | onChanged: (val) {
62 | setState(() {
63 | name = val.isEmpty ? "User" : val;
64 | });
65 | },
66 | ),
67 | SizedBox(
68 | height: 20.0,
69 | ),
70 | TextFormField(
71 | decoration: textInputDecoration.copyWith(
72 | prefixIcon: Icon(Icons.email), hintText: "Email ID"),
73 | validator: (val) {
74 | return val.isEmpty ? "Enter a valid email" : null;
75 | },
76 | onChanged: (val) {
77 | setState(() {
78 | email = val;
79 | });
80 | },
81 | ),
82 | SizedBox(
83 | height: 20.0,
84 | ),
85 | TextFormField(
86 | obscureText: true,
87 | decoration: textInputDecoration.copyWith(
88 | prefixIcon: Icon(Icons.lock), hintText: "Password"),
89 | validator: (val) {
90 | return val.length < 6
91 | ? "Oops! Password seems too short"
92 | : null;
93 | },
94 | onChanged: (val) {
95 | setState(() {
96 | password = val;
97 | });
98 | },
99 | ),
100 | SizedBox(
101 | height: 20.0,
102 | ),
103 | Row(
104 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
105 | children: [
106 | Container(
107 | child: InkWell(
108 | child: FlatButton(
109 | padding: EdgeInsets.all(0.0),
110 | shape: RoundedRectangleBorder(
111 | borderRadius: BorderRadius.circular(24.0)),
112 | onPressed: () async {
113 | //async action here
114 | if (_formKey.currentState.validate()) {
115 | dynamic res = await _auth.signInWithEmailAndPass(
116 | email, password, name);
117 | print(res);
118 | if (res == null) {
119 | Scaffold.of(context).showSnackBar(SnackBar(
120 | content: Text(
121 | "Something went wrong! Make sure your credentials are correct and retry!"),
122 | ));
123 | } else {
124 | widget.controller();
125 | Scaffold.of(context).showSnackBar(SnackBar(
126 | content: Text("Successfully logged in!"),
127 | ));
128 | }
129 | }
130 | },
131 | child: Ink(
132 | decoration: BoxDecoration(
133 | gradient: LinearGradient(
134 | colors: [Colors.teal, Colors.teal[200]],
135 | begin: Alignment.topLeft,
136 | end: Alignment.bottomRight,
137 | ),
138 | borderRadius: BorderRadius.circular(24.0)),
139 | child: Container(
140 | padding: EdgeInsets.symmetric(
141 | vertical: 12.0, horizontal: 30.0),
142 | child: Text(
143 | "SIGN IN",
144 | style: TextStyle(
145 | color: Colors.white,
146 | //fontWeight: FontWeight.bold,
147 | fontSize: 16.0,
148 | letterSpacing: 0.6,
149 | ),
150 | ),
151 | ),
152 | ),
153 | ),
154 | ),
155 | ),
156 | FlatButton(
157 | onPressed: () {
158 | widget.toggleView();
159 | },
160 | child: Text(
161 | 'Register?',
162 | ),
163 | )
164 | ],
165 | )
166 | ],
167 | ),
168 | ),
169 | ),
170 | ),
171 | );
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/lib/auth/register.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/widgets.dart';
3 | import 'package:sign_in/auth/constants.dart';
4 | import 'package:sign_in/services/AuthService.dart';
5 |
6 | class Register extends StatefulWidget {
7 | final Function toggleView, controller;
8 | Register({this.toggleView, this.controller});
9 | @override
10 | _RegisterState createState() => _RegisterState();
11 | }
12 |
13 | class _RegisterState extends State {
14 | final AuthService _auth = AuthService();
15 | final _formKey = GlobalKey();
16 | String email = "";
17 | String password = "";
18 | String cnfPass = "";
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return SingleChildScrollView(
23 | child: Container(
24 | padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 20.0),
25 | height: 500,
26 | child: Card(
27 | elevation: 8,
28 | shape: RoundedRectangleBorder(
29 | borderRadius: BorderRadius.circular(20.0),
30 | ),
31 | child: Form(
32 | key: _formKey,
33 | child: Padding(
34 | padding: const EdgeInsets.all(20.0),
35 | child: Column(
36 | mainAxisAlignment: MainAxisAlignment.spaceAround,
37 | children: [
38 | SizedBox(
39 | height: 10.0,
40 | ),
41 | Row(
42 | children: [
43 | Text(
44 | "RoverPy",
45 | style: TextStyle(
46 | fontSize: 30.0,
47 | color: Colors.amber,
48 | fontWeight: FontWeight.bold,
49 | letterSpacing: .6,
50 | ),
51 | ),
52 | ],
53 | ),
54 | SizedBox(
55 | height: 5.0,
56 | ),
57 | TextFormField(
58 | decoration: textInputDecoration.copyWith(
59 | prefixIcon: Icon(Icons.email), hintText: "Email ID"),
60 | validator: (val) {
61 | return val.isEmpty ? "Enter a valid email" : null;
62 | },
63 | onChanged: (val) {
64 | setState(() {
65 | email = val;
66 | });
67 | },
68 | ),
69 | SizedBox(
70 | height: 20.0,
71 | ),
72 | TextFormField(
73 | obscureText: true,
74 | decoration: textInputDecoration.copyWith(
75 | prefixIcon: Icon(Icons.lock), hintText: "Password"),
76 | validator: (val) {
77 | return val.length < 6
78 | ? "Oops! Password seems too short"
79 | : null;
80 | },
81 | onChanged: (val) {
82 | setState(() {
83 | password = val;
84 | });
85 | },
86 | ),
87 | SizedBox(
88 | height: 20.0,
89 | ),
90 | TextFormField(
91 | obscureText: true,
92 | decoration: textInputDecoration.copyWith(
93 | prefixIcon: Icon(Icons.lock_outline),
94 | hintText: "Confirm Password"),
95 | validator: (val) {
96 | return val.compareTo(password) != 0
97 | ? "Uh oh, Passwords do not match!"
98 | : null;
99 | },
100 | onChanged: (val) {
101 | setState(() {
102 | cnfPass = val;
103 | });
104 | },
105 | ),
106 | SizedBox(
107 | height: 20.0,
108 | ),
109 | Row(
110 | mainAxisAlignment: MainAxisAlignment.spaceEvenly,
111 | children: [
112 | Container(
113 | child: InkWell(
114 | child: FlatButton(
115 | padding: EdgeInsets.all(0.0),
116 | shape: RoundedRectangleBorder(
117 | borderRadius: BorderRadius.circular(24.0)),
118 | onPressed: () async {
119 | //async action here
120 | if (_formKey.currentState.validate()) {
121 | dynamic res = await _auth
122 | .registerWithEmailAndPass(email, password);
123 | print(res);
124 | if (res == null) {
125 | Scaffold.of(context).showSnackBar(SnackBar(
126 | content: Text(
127 | "Something went wrong! Make sure your credentials are correct and retry!"),
128 | ));
129 | } else {
130 | widget.controller();
131 | Scaffold.of(context).showSnackBar(SnackBar(
132 | content:
133 | Text("Account created successfully!"),
134 | ));
135 | }
136 | }
137 | },
138 | child: Ink(
139 | decoration: BoxDecoration(
140 | gradient: LinearGradient(
141 | colors: [Colors.teal, Colors.teal[200]],
142 | begin: Alignment.topLeft,
143 | end: Alignment.bottomRight,
144 | ),
145 | borderRadius: BorderRadius.circular(24.0)),
146 | child: Container(
147 | padding: EdgeInsets.symmetric(
148 | vertical: 12.0, horizontal: 30.0),
149 | child: Text(
150 | "REGISTER",
151 | style: TextStyle(
152 | color: Colors.white,
153 | //fontWeight: FontWeight.bold,
154 | fontSize: 16.0,
155 | letterSpacing: 0.6,
156 | ),
157 | ),
158 | ),
159 | ),
160 | ),
161 | ),
162 | ),
163 | FlatButton(
164 | onPressed: () {
165 | widget.toggleView();
166 | },
167 | child: Text(
168 | 'Sign In?',
169 | ),
170 | )
171 | ],
172 | )
173 | ],
174 | ),
175 | ),
176 | ),
177 | ),
178 | ),
179 | );
180 | }
181 | }
182 |
--------------------------------------------------------------------------------
/lib/commons/animated_popup.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/cupertino.dart';
3 | import 'package:quiver/async.dart';
4 | import 'package:sign_in/utils/data.dart';
5 |
6 | class AnimatedPopUp extends StatefulWidget {
7 | final List images;
8 |
9 | AnimatedPopUp({this.images});
10 | @override
11 | _AnimatedPopUpState createState() => _AnimatedPopUpState();
12 | }
13 |
14 | class _AnimatedPopUpState extends State {
15 | int elapsed = 0;
16 |
17 | void _incrementCounter() {
18 |
19 | final cd = CountdownTimer(Duration(seconds: widget.images.length-1), Duration(milliseconds: 500));
20 | cd.listen((data) {
21 | setState(() {
22 | elapsed = cd.elapsed.inSeconds;
23 | print(elapsed);
24 | });
25 | }, onDone: () {
26 | cd.cancel();
27 | Navigator.pop(context);
28 | });
29 |
30 | }
31 |
32 | @override
33 | void initState() {
34 | super.initState();
35 | WidgetsBinding.instance.addPostFrameCallback((timeStamp) {_incrementCounter();});
36 | }
37 |
38 | @override
39 | Widget build(BuildContext context) {
40 | return AnimatedSwitcher(
41 | child: Image(
42 | image: NetworkImage(widget.images[elapsed]),
43 | key: ValueKey(elapsed)),
44 | duration: Duration(seconds: 1),
45 | );
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/commons/collapsing_navigation_drawer.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:provider/provider.dart';
4 | import 'package:sign_in/commons/drawer_tile.dart';
5 | import 'package:sign_in/models/models_export.dart';
6 | import '../models/drawer_item.dart';
7 | import 'package:sign_in/services/AuthService.dart';
8 |
9 | import '../services/AuthService.dart';
10 |
11 | int currSelected = 0;
12 |
13 | class CollapsingNavDrawer extends StatefulWidget {
14 | @override
15 | _CollapsingNavDrawerState createState() => _CollapsingNavDrawerState();
16 | }
17 |
18 | class _CollapsingNavDrawerState extends State {
19 | @override
20 | Widget build(BuildContext context) {
21 | return Container(
22 | color: Theme.of(context).backgroundColor,
23 | width: MediaQuery.of(context).size.width / 2,
24 | child: Column(
25 | children: [
26 | Container(
27 | width: MediaQuery.of(context).size.width / 2,
28 | color: Theme.of(context).primaryColor,
29 | child: Column(
30 | children: [
31 | SizedBox(
32 | height: 35.0,
33 | ),
34 | Container(
35 | height: 50.0,
36 | child: Text('RoverPy',
37 | style: Theme.of(context).textTheme.headline5),
38 | ),
39 | ],
40 | )),
41 | Expanded(
42 | child: ListView.builder(
43 | itemCount: drawerList.length,
44 | itemBuilder: (context, index) {
45 | return InkWell(
46 | onTap: () {
47 | setState(() {
48 | currSelected = index;
49 | });
50 | Navigator.pushAndRemoveUntil(
51 | context,
52 | MaterialPageRoute(
53 | builder: (context) => drawerList[index].goToPage),
54 | (Route route) => false);
55 | },
56 | child: DrawerTile(
57 | isSelected: index == currSelected,
58 | iconData: drawerList[index].icon,
59 | title: drawerList[index].title,
60 | ),
61 | );
62 | }),
63 | ),
64 | GestureDetector(
65 | onTap: () {
66 | AuthService().logOut();
67 | },
68 | child: Container(
69 | child: Padding(
70 | padding: const EdgeInsets.all(8.0),
71 | child: Row(
72 | children: [
73 | Padding(
74 | padding: const EdgeInsets.all(8.0),
75 | child: Icon(
76 | Icons.lock_open,
77 | color: Theme.of(context).primaryColor,
78 | ),
79 | ),
80 | Padding(
81 | padding: const EdgeInsets.all(8.0),
82 | child: Text(
83 | 'Log out',
84 | style: TextStyle(
85 | fontSize: 18.0,
86 | color: Theme.of(context).primaryColor,
87 | fontWeight: FontWeight.w400,
88 | ),
89 | ),
90 | ),
91 | ],
92 | ),
93 | )),
94 | ),
95 | SizedBox(
96 | height: 35.0,
97 | ),
98 | Container(
99 | child: Consumer(
100 | builder: (context, themeProvider, child) {
101 | return Row(
102 | mainAxisAlignment: MainAxisAlignment.center,
103 | children: [
104 | Icon(
105 | Icons.brightness_7,
106 | size: 30.0,
107 | color: themeProvider.isDarkTheme
108 | ? Colors.grey
109 | : Theme.of(context).splashColor,
110 | ),
111 | Switch(
112 | value: themeProvider.isDarkTheme,
113 | onChanged: (value) {
114 | themeProvider.isDarkTheme = value;
115 | },
116 | ),
117 | Icon(
118 | Icons.brightness_2,
119 | size: 30.0,
120 | color: themeProvider.isDarkTheme
121 | ? Theme.of(context).splashColor
122 | : Colors.grey,
123 | )
124 | ],
125 | );
126 | },
127 | ),
128 | ),
129 | ],
130 | ),
131 | );
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/lib/commons/custom_card.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:url_launcher/url_launcher.dart';
3 |
4 | class CustomCard extends StatefulWidget {
5 | final String name;
6 | final String image;
7 | final String url;
8 | final String subtitle;
9 | final int i;
10 | CustomCard({ this.name, this.image, this.url, this.subtitle, this.i});
11 | @override
12 | _CustomCardState createState() => _CustomCardState();
13 | }
14 |
15 | class _CustomCardState extends State {
16 | @override
17 | Widget build(BuildContext context) {
18 | return Card(
19 | child: Container(
20 | padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 12.0),
21 | child: ListTile(
22 | leading: Hero(
23 | tag: "Profile${widget.i}",
24 | child: Material(
25 | type: MaterialType.transparency,
26 | child: CircleAvatar(
27 | backgroundImage: NetworkImage(widget.image),
28 | radius: 20.0,
29 | ),
30 | ),
31 | ),
32 | title: Hero(
33 | tag: "Name${widget.i}",
34 | child: Material(
35 | type: MaterialType.transparency,
36 | child: Text(
37 | widget.name,
38 | style: TextStyle(
39 | fontSize: 20.0,
40 | color: Colors.black,
41 | ),
42 | ),
43 | )
44 | ),
45 | trailing: InkWell(
46 | onTap: (){
47 | launch(widget.url);
48 | },
49 | child: CircleAvatar(
50 | backgroundColor: Colors.black,
51 | backgroundImage: AssetImage('assets/github_logo.png'),
52 | radius: 15.0,
53 | ),
54 | )
55 | ),
56 | ),
57 | );
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/lib/commons/drawer_tile.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 |
3 | class DrawerTile extends StatefulWidget {
4 | final IconData iconData;
5 | final String title;
6 | final bool isSelected;
7 |
8 | DrawerTile({this.iconData, this.title, this.isSelected});
9 |
10 | @override
11 | _DrawerTileState createState() => _DrawerTileState();
12 | }
13 |
14 | class _DrawerTileState extends State {
15 | @override
16 | Widget build(BuildContext context) {
17 | return Container(
18 | height: 50.0,
19 | child: Row(
20 | mainAxisAlignment: MainAxisAlignment.start,
21 | children: [
22 | Padding(
23 | padding: const EdgeInsets.all(8.0),
24 | child: Icon(widget.iconData, color: widget.isSelected?Theme.of(context).splashColor: Theme.of(context).primaryColor,),
25 | ),
26 | Padding(
27 | padding: const EdgeInsets.all(8.0),
28 | child: Text(
29 | '${widget.title}',
30 | style: TextStyle(
31 | fontSize: 18.0,
32 | color: widget.isSelected?Theme.of(context).splashColor: Theme.of(context).primaryColor,
33 | fontWeight: widget.isSelected?FontWeight.w600:FontWeight.w400,
34 | ),
35 | ),
36 | ),
37 | ],
38 | ),
39 | );
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/lib/commons/stepper_control.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:flutter/physics.dart';
4 |
5 | class StepperTouch extends StatefulWidget {
6 | StepperTouch({
7 | Key key,
8 | this.size = 300.0,
9 | this.onEnd,
10 | this.onHoldDown,
11 | @required this.initialValue,
12 | @required this.positiveValue,
13 | @required this.negativeValue,
14 | this.direction = Axis.horizontal,
15 | this.withSpring = true,
16 | }) : super(key: key);
17 |
18 | /// the orientation of the stepper its horizontal or vertical.
19 | final Axis direction;
20 |
21 | final String initialValue;
22 | final String positiveValue;
23 | final String negativeValue;
24 |
25 | /// called whenever the stepper is released
26 | final ValueChanged onEnd;
27 |
28 | /// called whenever the stepper is moved
29 | final ValueChanged onHoldDown;
30 |
31 | /// if you want a springSimulation to happens the the user let go the stepper
32 | /// defaults to true
33 | final bool withSpring;
34 | final double size;
35 | final Color buttonsColor = Color.fromRGBO(0, 255, 255, 1);
36 |
37 | @override
38 | _Stepper2State createState() => _Stepper2State();
39 | }
40 |
41 | class _Stepper2State extends State
42 | with SingleTickerProviderStateMixin {
43 | AnimationController _controller;
44 | Animation _animation;
45 | Color _color;
46 | String _value;
47 | double _startAnimationPosX;
48 | double _startAnimationPosY;
49 |
50 | @override
51 | void initState() {
52 | super.initState();
53 | _value = widget.initialValue;
54 | _color = Color.fromRGBO(0, 255, 255, 1);
55 | _controller =
56 | AnimationController(vsync: this, lowerBound: -0.5, upperBound: 0.5);
57 | _controller.value = 0.0;
58 | _controller.addListener(() {});
59 |
60 | if (widget.direction == Axis.horizontal) {
61 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(0.5, 0.0))
62 | .animate(_controller);
63 | } else {
64 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(0.0, 1.5))
65 | .animate(_controller);
66 | }
67 | }
68 |
69 | @override
70 | void dispose() {
71 | _controller?.dispose();
72 | super.dispose();
73 | }
74 |
75 | @override
76 | void didUpdateWidget(oldWidget) {
77 | super.didUpdateWidget(oldWidget);
78 | if (widget.direction == Axis.horizontal) {
79 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(0.5, 0.0))
80 | .animate(_controller);
81 | } else {
82 | _animation = Tween(begin: Offset(0.0, 0.0), end: Offset(0.0, 1.5))
83 | .animate(_controller);
84 | }
85 | }
86 |
87 | @override
88 | Widget build(BuildContext context) {
89 | return FittedBox(
90 | child: Container(
91 | width: widget.direction == Axis.horizontal
92 | ? widget.size
93 | : widget.size / 2 - 30.0,
94 | height: widget.direction == Axis.horizontal
95 | ? widget.size / 2 - 30.0
96 | : widget.size,
97 | child: Material(
98 | type: MaterialType.canvas,
99 | clipBehavior: Clip.antiAlias,
100 | borderRadius: BorderRadius.circular(60.0),
101 | color: Colors.blue.withOpacity(0.2),
102 | child: Stack(
103 | alignment: Alignment.center,
104 | children: [
105 | Positioned(
106 | left: widget.direction == Axis.horizontal ? 10.0 : null,
107 | bottom: widget.direction == Axis.horizontal ? null : 10.0,
108 | child: Icon(
109 | widget.direction == Axis.horizontal
110 | ? Icons.arrow_left
111 | : Icons.arrow_drop_down,
112 | size: 40.0,
113 | color: widget.buttonsColor),
114 | ),
115 | Positioned(
116 | right: widget.direction == Axis.horizontal ? 10.0 : null,
117 | top: widget.direction == Axis.horizontal ? null : 10.0,
118 | child: Icon(
119 | widget.direction == Axis.horizontal
120 | ? Icons.arrow_right
121 | : Icons.arrow_drop_up,
122 | size: 40.0,
123 | color: widget.buttonsColor),
124 | ),
125 | GestureDetector(
126 | onHorizontalDragStart: _onPanStart,
127 | onHorizontalDragUpdate: _onPanUpdate,
128 | onHorizontalDragEnd: _onPanEnd,
129 | child: SlideTransition(
130 | position: _animation,
131 | child: Material(
132 | shape: const CircleBorder(),
133 | child: AnimatedContainer(
134 | duration: Duration(milliseconds: 500),
135 | height: widget.size / 3,
136 | decoration: BoxDecoration(
137 | color: _color,
138 | shape: BoxShape.circle,
139 | ),
140 | curve: Curves.linear,
141 | ),
142 | elevation: 5.0,
143 | ),
144 | ),
145 | ),
146 | ],
147 | ),
148 | ),
149 | ),
150 | );
151 | }
152 |
153 | double offsetFromGlobalPos(Offset globalPosition) {
154 | RenderBox box = context.findRenderObject() as RenderBox;
155 | Offset local = box.globalToLocal(globalPosition);
156 | _startAnimationPosX = ((local.dx * 0.75) / box.size.width) - 0.4;
157 | _startAnimationPosY = ((local.dy * 0.75) / box.size.height) - 0.4;
158 | if (widget.direction == Axis.horizontal) {
159 | return ((local.dx * 0.75) / box.size.width) - 0.4;
160 | } else {
161 | return ((local.dy * 0.75) / box.size.height) - 0.4;
162 | }
163 | }
164 |
165 | void _onPanStart(DragStartDetails details) {
166 | _controller.stop();
167 | _controller.value = offsetFromGlobalPos(details.globalPosition);
168 | }
169 |
170 | void _onPanUpdate(DragUpdateDetails details) {
171 | _controller.value = offsetFromGlobalPos(details.globalPosition);
172 | setState(() {
173 | //int r = 0 + ((_controller.value * 2).abs() * 255).round();
174 | int g = 255 - ((_controller.value * 2).abs() * 255).round();
175 | _color = Color.fromRGBO(0, g, 255, 1);
176 | });
177 | if (_controller.value <= -0.10) {
178 | setState(() => _value = widget.positiveValue);
179 | } else if (_controller.value >= 0.10) {
180 | setState(() => _value = widget.negativeValue);
181 | }
182 | if (widget.onHoldDown != null) {
183 | widget.onHoldDown(_value);
184 | }
185 | }
186 |
187 | void _onPanEnd(DragEndDetails details) {
188 | _controller.stop();
189 | if (widget.withSpring) {
190 | final SpringDescription _kDefaultSpring =
191 | new SpringDescription.withDampingRatio(
192 | mass: 0.9,
193 | stiffness: 250.0,
194 | ratio: 0.6,
195 | );
196 | if (widget.direction == Axis.horizontal) {
197 | _controller.animateWith(
198 | SpringSimulation(_kDefaultSpring, _startAnimationPosX, 0.0, 0.0));
199 | } else {
200 | _controller.animateWith(
201 | SpringSimulation(_kDefaultSpring, _startAnimationPosY, 0.0, 0.0));
202 | }
203 | } else {
204 | _controller.animateTo(0.0,
205 | curve: Curves.bounceOut, duration: Duration(milliseconds: 500));
206 | }
207 | _value = widget.initialValue;
208 | if (widget.onEnd != null) {
209 | widget.onEnd(_value);
210 | }
211 | setState(() {
212 | _color = Color.fromRGBO(0, 255, 255, 1);
213 | });
214 | }
215 | }
216 |
--------------------------------------------------------------------------------
/lib/helpers/map_helper.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 | import 'dart:typed_data';
4 | import 'dart:ui';
5 | import 'package:http/http.dart' as http;
6 |
7 | import 'package:fluster/fluster.dart';
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_cache_manager/flutter_cache_manager.dart';
10 | import 'package:sign_in/helpers/map_marker.dart';
11 | import 'package:google_maps_flutter/google_maps_flutter.dart';
12 |
13 | /// In here we are encapsulating all the logic required to get marker icons from url images
14 | /// and to show clusters using the [Fluster] package.
15 | class MapHelper {
16 | /// If there is a cached file and it's not old returns the cached marker image file
17 | /// else it will download the image and save it on the temp dir and return that file.
18 | ///
19 | /// This mechanism is possible using the [DefaultCacheManager] package and is useful
20 | /// to improve load times on the next map loads, the first time will always take more
21 | /// time to download the file and set the marker image.
22 | ///
23 | /// You can resize the marker image by providing a [targetWidth].
24 | static Future getMarkerImageFromUrl(
25 | String url, {
26 | int targetWidth,
27 | }) async {
28 | assert(url != null);
29 |
30 | // final File markerImageFile = await DefaultCacheManager().getSingleFile(url);
31 |
32 | http.Response res = await http.get(url);
33 |
34 | Uint8List markerImageBytes = res.bodyBytes;
35 |
36 | if (targetWidth != null) {
37 | markerImageBytes = await _resizeImageBytes(
38 | markerImageBytes,
39 | targetWidth,
40 | );
41 | }
42 |
43 | return BitmapDescriptor.fromBytes(markerImageBytes);
44 | }
45 |
46 | /// Draw a [clusterColor] circle with the [clusterSize] text inside that is [width] wide.
47 | ///
48 | /// Then it will convert the canvas to an image and generate the [BitmapDescriptor]
49 | /// to be used on the cluster marker icons.
50 | static Future _getClusterMarker(
51 | int clusterSize,
52 | Color clusterColor,
53 | Color textColor,
54 | int width,
55 | ) async {
56 | assert(clusterSize != null);
57 | assert(clusterColor != null);
58 | assert(width != null);
59 |
60 | final PictureRecorder pictureRecorder = PictureRecorder();
61 | final Canvas canvas = Canvas(pictureRecorder);
62 | final Paint paint = Paint()..color = clusterColor;
63 | final TextPainter textPainter = TextPainter(
64 | textDirection: TextDirection.ltr,
65 | );
66 |
67 | final double radius = width / 2;
68 |
69 | canvas.drawCircle(
70 | Offset(radius, radius),
71 | radius,
72 | paint,
73 | );
74 |
75 | textPainter.text = TextSpan(
76 | text: clusterSize.toString(),
77 | style: TextStyle(
78 | fontSize: radius - 5,
79 | fontWeight: FontWeight.bold,
80 | color: textColor,
81 | ),
82 | );
83 |
84 | textPainter.layout();
85 | textPainter.paint(
86 | canvas,
87 | Offset(radius - textPainter.width / 2, radius - textPainter.height / 2),
88 | );
89 |
90 | final image = await pictureRecorder.endRecording().toImage(
91 | radius.toInt() * 2,
92 | radius.toInt() * 2,
93 | );
94 | final data = await image.toByteData(format: ImageByteFormat.png);
95 |
96 | return BitmapDescriptor.fromBytes(data.buffer.asUint8List());
97 | }
98 |
99 | /// Resizes the given [imageBytes] with the [targetWidth].
100 | ///
101 | /// We don't want the marker image to be too big so we might need to resize the image.
102 | static Future _resizeImageBytes(
103 | Uint8List imageBytes,
104 | int targetWidth,
105 | ) async {
106 | assert(imageBytes != null);
107 | assert(targetWidth != null);
108 |
109 | final Codec imageCodec = await instantiateImageCodec(
110 | imageBytes,
111 | targetWidth: targetWidth,
112 | );
113 |
114 | final FrameInfo frameInfo = await imageCodec.getNextFrame();
115 |
116 | final ByteData byteData = await frameInfo.image.toByteData(
117 | format: ImageByteFormat.png,
118 | );
119 |
120 | return byteData.buffer.asUint8List();
121 | }
122 |
123 | /// Inits the cluster manager with all the [MapMarker] to be displayed on the map.
124 | /// Here we're also setting up the cluster marker itself, also with an [clusterImageUrl].
125 | ///
126 | /// For more info about customizing your clustering logic check the [Fluster] constructor.
127 | static Future> initClusterManager(
128 | List markers,
129 | int minZoom,
130 | int maxZoom,
131 | ) async {
132 | assert(markers != null);
133 | assert(minZoom != null);
134 | assert(maxZoom != null);
135 |
136 | return Fluster(
137 | minZoom: minZoom,
138 | maxZoom: maxZoom,
139 | radius: 150,
140 | extent: 2048,
141 | nodeSize: 64,
142 | points: markers,
143 | createCluster: (
144 | BaseCluster cluster,
145 | double lng,
146 | double lat,
147 | ) =>
148 | MapMarker(
149 | id: cluster.id.toString(),
150 | position: LatLng(lat, lng),
151 | isCluster: cluster.isCluster,
152 | clusterId: cluster.id,
153 | pointsSize: cluster.pointsSize,
154 | childMarkerId: cluster.childMarkerId,
155 | ),
156 | );
157 | }
158 |
159 | /// Gets a list of markers and clusters that reside within the visible bounding box for
160 | /// the given [currentZoom]. For more info check [Fluster.clusters].
161 | static Future> getClusterMarkers(
162 | Fluster clusterManager,
163 | double currentZoom,
164 | Color clusterColor,
165 | Color clusterTextColor,
166 | int clusterWidth,
167 | ) {
168 | assert(currentZoom != null);
169 | assert(clusterColor != null);
170 | assert(clusterTextColor != null);
171 | assert(clusterWidth != null);
172 |
173 | if (clusterManager == null) return Future.value([]);
174 |
175 | return Future.wait(clusterManager.clusters(
176 | [-180, -85, 180, 85], currentZoom.toInt()).map((mapMarker) async {
177 | if (mapMarker.isCluster) {
178 | mapMarker.icon = await _getClusterMarker(
179 | mapMarker.pointsSize,
180 | clusterColor,
181 | clusterTextColor,
182 | clusterWidth,
183 | );
184 | }
185 |
186 | return mapMarker.toMarker();
187 | }).toList());
188 | }
189 | }
--------------------------------------------------------------------------------
/lib/helpers/map_marker.dart:
--------------------------------------------------------------------------------
1 | import 'package:fluster/fluster.dart';
2 | import 'package:google_maps_flutter/google_maps_flutter.dart';
3 | import 'package:meta/meta.dart';
4 |
5 | /// [Fluster] can only handle markers that conform to the [Clusterable] abstract class.
6 | ///
7 | /// You can customize this class by adding more parameters that might be needed for
8 | /// your use case. For instance, you can pass an onTap callback or add an
9 | /// [InfoWindow] to your marker here, then you can use the [toMarker] method to convert
10 | /// this to a proper [Marker] that the [GoogleMap] can read.
11 | class MapMarker extends Clusterable {
12 | final String id;
13 | final LatLng position;
14 | BitmapDescriptor icon;
15 |
16 | MapMarker({
17 | @required this.id,
18 | @required this.position,
19 | this.icon,
20 | isCluster = false,
21 | clusterId,
22 | pointsSize,
23 | childMarkerId,
24 | }) : super(
25 | markerId: id,
26 | latitude: position.latitude,
27 | longitude: position.longitude,
28 | isCluster: isCluster,
29 | clusterId: clusterId,
30 | pointsSize: pointsSize,
31 | childMarkerId: childMarkerId,
32 | );
33 |
34 | Marker toMarker() => Marker(
35 | markerId: MarkerId(isCluster ? 'cl_$id' : id),
36 | position: LatLng(
37 | position.latitude,
38 | position.longitude,
39 | ),
40 | icon: icon,
41 | );
42 | }
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:sign_in/wrapper.dart';
3 | import './services/AuthService.dart';
4 | import 'package:provider/provider.dart';
5 | import 'package:firebase_auth/firebase_auth.dart';
6 |
7 | void main() => runApp(MyApp());
8 |
9 | class MyApp extends StatelessWidget {
10 | @override
11 | Widget build(BuildContext context) {
12 | return StreamProvider.value(
13 | value: AuthService().userDetail, child: Wrapper());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/models/developer_info.dart:
--------------------------------------------------------------------------------
1 | class DevInfo {
2 | final String name;
3 | final String gitLink;
4 | final String imageLink;
5 | final String otherInfo;
6 | final Details deets;
7 |
8 | DevInfo(
9 | {this.name, this.gitLink, this.imageLink, this.otherInfo, this.deets});
10 | }
11 |
12 | List developers = [
13 | DevInfo(
14 | name: 'Miheer',
15 | gitLink: 'https://github.com/mimi69-38',
16 | imageLink: 'assets/Miheer.png',
17 | otherInfo: 'very USEFUL member of our team'),
18 | DevInfo(
19 | name: 'Pratit',
20 | gitLink: 'https://github.com/Pratit23',
21 | imageLink: 'assets/Pratit.png',
22 | otherInfo: 'an actually useful member of the team'),
23 | DevInfo(
24 | name: 'Aajinkya',
25 | gitLink: 'https://github.com/aajinkya1203',
26 | imageLink: 'assets/Aajinkya.jpg',
27 | otherInfo: 'another actually useful member of the team'),
28 | DevInfo(
29 | name: 'Aditi',
30 | gitLink: 'https://github.com/Aditi-Mohan',
31 | imageLink: 'assets/Aditi.png',
32 | otherInfo: 'we do bruh. about jiggy too!'),
33 | ];
34 |
35 | class Details {}
36 |
--------------------------------------------------------------------------------
/lib/models/drawer_item.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/cupertino.dart';
3 | import 'package:sign_in/commons/stepper_control.dart';
4 | import 'package:sign_in/services/MainPage.dart';
5 | import '../pages/pages_export.dart';
6 |
7 | class DrawerItem {
8 | final String title;
9 | final IconData icon;
10 | final Widget goToPage;
11 |
12 | DrawerItem({this.title, this.icon, this.goToPage});
13 | }
14 |
15 | List drawerList = [
16 | DrawerItem(icon: Icons.home, title: 'Home', goToPage: HomePage()),
17 | DrawerItem(
18 | icon: Icons.swap_calls, title: 'Control Rover', goToPage: ControlsPage()),
19 | DrawerItem(icon: Icons.spa, title: 'Report', goToPage: ReportPage()),
20 | DrawerItem(icon: Icons.spa, title: 'Bluetooth', goToPage: MainPage()),
21 | ];
22 |
--------------------------------------------------------------------------------
/lib/models/models_export.dart:
--------------------------------------------------------------------------------
1 | export 'drawer_item.dart';
2 | export 'theme_model.dart';
--------------------------------------------------------------------------------
/lib/models/series_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:charts_flutter/flutter.dart' as charts;
2 |
3 | class SeriesModel {
4 | final String label;
5 | final int count;
6 | final charts.Color color;
7 |
8 | SeriesModel({this.label, this.count, this.color});
9 | }
10 |
11 | class Label {
12 | final String label;
13 | final String url;
14 | final double confidence;
15 |
16 | Label({this.label, this.url, this.confidence});
17 | }
--------------------------------------------------------------------------------
/lib/models/theme_model.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:shared_preferences/shared_preferences.dart';
3 |
4 | class ThemePreference {
5 |
6 | Future getThemePreference() async {
7 | SharedPreferences pref = await SharedPreferences.getInstance();
8 | return pref.getBool('isDarkTheme')??false;
9 | }
10 |
11 | Future setThemePreference(bool value) async {
12 | SharedPreferences pref = await SharedPreferences.getInstance();
13 | pref.setBool('isDarkTheme', value);
14 | }
15 | }
16 |
17 | class DarkThemeProvider extends ChangeNotifier {
18 | ThemePreference themePreference = ThemePreference();
19 | static bool _isDarkTheme = false;
20 |
21 | bool get isDarkTheme => _isDarkTheme;
22 |
23 | set isDarkTheme(bool value) {
24 | _isDarkTheme = value;
25 | themePreference.setThemePreference(value);
26 | notifyListeners();
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/lib/models/user.dart:
--------------------------------------------------------------------------------
1 | class User {
2 | final String uid;
3 |
4 | User({this.uid}) {
5 | currUser = this;
6 | }
7 | }
8 |
9 | User currUser;
10 |
--------------------------------------------------------------------------------
/lib/pages/QuickAccess.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | class QuickAccess
4 | {
5 | final String jobTitle;
6 | final String jobLocation;
7 | final String companyImageSource;
8 | final Color backgroundColor;
9 |
10 | QuickAccess(this.jobTitle, this.jobLocation, this.companyImageSource, this.backgroundColor);
11 | }
--------------------------------------------------------------------------------
/lib/pages/Specific.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:sign_in/models/developer_info.dart';
3 | import 'package:url_launcher/url_launcher.dart';
4 |
5 | class Specific extends StatefulWidget {
6 | final DevInfo info;
7 | final int i;
8 | final String url;
9 | Specific({this.info, this.i, this.url});
10 | @override
11 | _SpecificState createState() => _SpecificState();
12 | }
13 |
14 | class _SpecificState extends State {
15 | List colorList = [
16 | new Color(0xffff5f6d),
17 | new Color(0xffffc371),
18 | new Color(0xff43cea2),
19 | new Color(0xff185a9d),
20 | new Color(0xff4568dc),
21 | new Color(0xffb06ab3),
22 | new Color(0xffeecda3),
23 | new Color(0xffef629f)
24 | ];
25 |
26 | @override
27 | Widget build(BuildContext context) {
28 | return Scaffold(
29 | backgroundColor: new Color(0xff333333),
30 | body: Stack(
31 | // alignment: Alignment.center,
32 | children: [
33 | Container(
34 | width: MediaQuery.of(context).size.width,
35 | height: 1 / 3 * MediaQuery.of(context).size.height,
36 | decoration: BoxDecoration(
37 | gradient: LinearGradient(
38 | begin: Alignment.topRight,
39 | end: Alignment.bottomLeft,
40 | colors: [colorList[2*(widget.i)], colorList[2*(widget.i)+1]],
41 | ),
42 | borderRadius: BorderRadius.only(
43 | bottomLeft: Radius.circular(24.0),
44 | bottomRight: Radius.circular(24.0),
45 | ),
46 | ),
47 | ),
48 | Positioned(
49 | top: 1 / 3 * MediaQuery.of(context).size.height - 41.5,
50 | left: 1 / 2 * MediaQuery.of(context).size.width - 41.5,
51 | child: Hero(
52 | tag: "Profile${widget.i}",
53 | child: Material(
54 | type: MaterialType.transparency,
55 | child: CircleAvatar(
56 | backgroundImage: AssetImage(widget.info.imageLink),
57 | radius: 45.0,
58 | ),
59 | ),
60 | ),
61 | ),
62 | Row(
63 | mainAxisAlignment: MainAxisAlignment.center,
64 | children: [
65 | Column(
66 | mainAxisAlignment: MainAxisAlignment.center,
67 | children: [
68 | Hero(
69 | tag: "Name${widget.i}",
70 | child: Material(
71 | type: MaterialType.transparency,
72 | child: Text(
73 | widget.info.name,
74 | style: TextStyle(
75 | fontSize: 40.0,
76 | color: Colors.white,
77 | ),
78 | ),
79 | ),
80 | ),
81 | Text(widget.info.otherInfo.toString(),
82 | style: TextStyle(
83 | fontSize: 16.0,
84 | color: new Color(0xffff958d),
85 | )),
86 | ]),
87 | ],
88 | ),
89 | ],
90 | ),
91 | floatingActionButton: FloatingActionButton(
92 | heroTag: 'fab',
93 | onPressed: () {
94 | launch(widget.url);
95 | },
96 | tooltip: "Github",
97 | child: Icon(Icons.code),
98 | ),
99 | );
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/lib/pages/about.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/cupertino.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:sign_in/commons/custom_card.dart';
4 | import 'package:sign_in/models/developer_info.dart';
5 | import 'package:sign_in/pages/Specific.dart';
6 |
7 | class AboutUs extends StatefulWidget {
8 | @override
9 | _AboutUsState createState() => _AboutUsState();
10 | }
11 |
12 | class _AboutUsState extends State {
13 |
14 |
15 | @override
16 | Widget build(BuildContext context) {
17 | return Scaffold(
18 | backgroundColor: Theme.of(context).backgroundColor,
19 | body: Column(
20 | children: [
21 | SizedBox(height: 40.0,),
22 | Card(
23 | color: Colors.transparent,
24 | child: ClipPath(
25 | clipper: ShapeBorderClipper(
26 | shape: RoundedRectangleBorder(
27 | borderRadius: BorderRadius.circular(20.0)
28 | ),
29 | ),
30 | child: Container(
31 | height: MediaQuery.of(context).size.height/4,
32 | width: MediaQuery.of(context).size.width,
33 | padding: EdgeInsets.symmetric(vertical: 50.0, horizontal: 40.0),
34 | decoration: BoxDecoration(
35 | image: DecorationImage(
36 | image: AssetImage('assets/aboutUs.png'),
37 | fit: BoxFit.cover
38 | )
39 | ),
40 | child: Column(
41 | crossAxisAlignment: CrossAxisAlignment.center,
42 | children: [
43 | SizedBox(height: 20,),
44 | Container(
45 | margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
46 | decoration: BoxDecoration(
47 | border: Border.all(
48 | color: Colors.black,
49 | width: 3.0,
50 | ),
51 | borderRadius: BorderRadius.circular(20.0)
52 | ),
53 | child: Text(
54 | "About Us",
55 | style: TextStyle(
56 | fontFamily: 'Lexend_Deca',
57 | color: Colors.black,
58 | fontWeight: FontWeight.bold,
59 | fontSize: 35.0
60 | ),
61 | ),
62 | ),
63 | ],
64 | ),
65 | ),
66 | ),
67 | ),
68 | Expanded(
69 | child: ListView.builder(
70 | itemCount: developers.length,
71 | itemBuilder: (context, index) {
72 | // return InkWell(
73 | // onTap: (){
74 | // Navigator.push(context, MaterialPageRoute(builder: (_)=>Specific(
75 | // info: developers[index],
76 | // i:index,
77 | // url: developers[index].gitLink,
78 | // )
79 | // )
80 | // );
81 | // },
82 | // child: CustomCard(
83 | // i: index,
84 | // name: developers[index].name,
85 | // image: developers[index].imageLink,
86 | // subtitle: developers[index].otherInfo,
87 | // url: developers[index].gitLink,
88 | // ),
89 | // );
90 | return SafeArea(
91 | child: Column(
92 | children: [
93 | CupertinoButton(
94 | child: Container(
95 | height: 150,
96 | width: MediaQuery.of(context).size.width,
97 | decoration: BoxDecoration(
98 | image: DecorationImage(
99 | image: AssetImage("assets/RoverDev$index.jpg"),
100 | fit: BoxFit.cover,
101 | ),
102 | borderRadius: BorderRadius.circular(12),
103 | ),
104 | child: Row(
105 | crossAxisAlignment: CrossAxisAlignment.start,
106 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
107 | children: [
108 | Container(
109 | margin: EdgeInsets.fromLTRB(15, 15, 0, 0),
110 | child: Hero(
111 | tag: "Name$index",
112 | child: Material(
113 | type: MaterialType.transparency,
114 | child: Text(
115 | developers[index].name,
116 | style: TextStyle(
117 | color: Colors.white,
118 | fontSize: 20,
119 | fontWeight: FontWeight.w600),
120 | ),
121 | ),
122 | ),
123 | ),
124 | Container(
125 | // height: 50.0,
126 | // alignment: Alignment.centerLeft,
127 | margin: EdgeInsets.fromLTRB(0, 10, 15, 0),
128 | child: Hero(
129 | tag: "Profile$index",
130 | child: Material(
131 | type: MaterialType.transparency,
132 | child: CircleAvatar(
133 | backgroundImage: AssetImage(developers[index].imageLink),
134 | radius: 20.0,
135 | ),
136 | ),
137 | ),
138 | )
139 | ],
140 | ),
141 | ),
142 | onPressed: () {
143 | Navigator.push(context, MaterialPageRoute(builder: (_)=>Specific(
144 | info: developers[index],
145 | i:index,
146 | url: developers[index].gitLink,
147 | )
148 | )
149 | );
150 | },
151 | ),
152 | ],
153 | ),
154 | );
155 | },
156 | ),
157 | ),
158 | ],
159 | ),
160 | floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
161 | floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling,
162 | floatingActionButton: FloatingActionButton(
163 | heroTag: 'fab',
164 | onPressed: () {
165 | Navigator.of(context).pop();
166 | },
167 | elevation: 5.0,
168 | tooltip: "Go back",
169 | child: Icon(Icons.arrow_back),
170 | ),
171 | );
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/lib/pages/constants_profile.dart:
--------------------------------------------------------------------------------
1 | import 'dart:ui';
2 |
3 | final Color secondaryColor = Color(0xFFF0F0F0);
4 | final Color primaryColor = Color(0xFFFF7E7E);
5 |
6 | final Color lightYellowColor = Color(0xFFFFF9DE);
7 | final Color lightGreenColor = Color(0xFFDEFFDF);
8 | final Color lightPurpleColor = Color(0xFFEBDEFF);
9 |
--------------------------------------------------------------------------------
/lib/pages/map_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:fluster/fluster.dart';
4 | import 'package:flutter/material.dart';
5 | import 'package:google_maps_flutter/google_maps_flutter.dart';
6 | import 'package:intl/intl.dart';
7 | import 'package:sign_in/helpers/map_helper.dart';
8 | import 'package:sign_in/helpers/map_marker.dart';
9 | import 'package:cloud_firestore/cloud_firestore.dart';
10 | import 'package:sign_in/models/user.dart';
11 |
12 | class MapPage extends StatefulWidget {
13 | @override
14 | _MapPageState createState() => _MapPageState();
15 | }
16 |
17 | class _MapPageState extends State {
18 | final Completer _mapController = Completer();
19 |
20 | /// Set of displayed markers and cluster markers on the map
21 | final Set _markers = Set();
22 |
23 | /// Minimum zoom at which the markers will cluster
24 | final int _minClusterZoom = 0;
25 |
26 | /// Maximum zoom at which the markers will cluster
27 | final int _maxClusterZoom = 19;
28 |
29 | /// [Fluster] instance used to manage the clusters
30 | Fluster _clusterManager;
31 |
32 | /// Current map zoom. Initial zoom will be 15, street level
33 | double _currentZoom = 15;
34 |
35 | /// Map loading flag
36 | bool _isMapLoading = true;
37 |
38 | /// Markers loading flag
39 | bool _areMarkersLoading = true;
40 |
41 | /// Url image used on normal markers
42 | final String _markerImageUrl =
43 | 'https://firebasestorage.googleapis.com/v0/b/roverpy-aamp.appspot.com/o/map_icon_rs.png?alt=media&token=f8fb0564-30f1-4f84-b14a-a02f8d731763';
44 |
45 | final String _unhealthyMarkerImageUrl = 'https://firebasestorage.googleapis.com/v0/b/roverpy-aamp.appspot.com/o/map_icon_un.png?alt=media&token=af8b990f-6cba-4932-99a8-cbc85e36d724';
46 |
47 | /// Color of the cluster circle
48 | final Color _clusterColor = Colors.blue;
49 |
50 | /// Color of the cluster text
51 | final Color _clusterTextColor = Colors.white;
52 |
53 | final List _labels = [];
54 |
55 | /// Example marker coordinates
56 | final List _markerLocations = [
57 | // LatLng(41.147125, -8.611249),
58 | // LatLng(41.145599, -8.610691),
59 | // LatLng(41.145645, -8.614761),
60 | // LatLng(41.146775, -8.614913),
61 | // LatLng(41.146982, -8.615682),
62 | // LatLng(41.140558, -8.611530),
63 | // LatLng(41.138393, -8.608642),
64 | // LatLng(41.137860, -8.609211),
65 | // LatLng(41.138344, -8.611236),
66 | // LatLng(41.139813, -8.609381),
67 | ];
68 |
69 | /// Called when the Google Map widget is created. Updates the map loading state
70 | /// and inits the markers.
71 | void _onMapCreated(GoogleMapController controller) {
72 | _mapController.complete(controller);
73 |
74 | setState(() {
75 | _isMapLoading = false;
76 | });
77 |
78 | _initMarkers();
79 | }
80 |
81 | /// Inits [Fluster] and all the markers with network images and updates the loading state.
82 | void _initMarkers() async {
83 | final List markers = [];
84 | String lastUsed;
85 |
86 | DocumentSnapshot userDoc = await Firestore.instance.collection('users').document('HHJjcEassOW3nRJEE65tYXmTJzn2').get();
87 | lastUsed = userDoc.data['lastUsed'];
88 | print(lastUsed);
89 |
90 | QuerySnapshot docs = await Firestore.instance.collection('users').document('HHJjcEassOW3nRJEE65tYXmTJzn2').collection(lastUsed).getDocuments();
91 |
92 | // docs.documents.forEach((element) {
93 | // _markerLocations.add(LatLng(element.data['lat'], element.data['lng']));
94 | // _labels.add(element.data['label']);
95 | // });
96 |
97 | for (int i=0; i< docs.documents.length; i++) {
98 | print('${docs.documents[i].data['lat']} ${docs.documents[i].data['lng']}');
99 | if (docs.documents[i].documentID != 'report') {
100 | LatLng markerLocation = LatLng(docs.documents[i].data['lat'], docs.documents[i].data['lng']);
101 | _markerLocations.add(markerLocation);
102 |
103 | final BitmapDescriptor markerImage =
104 | await MapHelper.getMarkerImageFromUrl(docs.documents[i].data['label'] == 'healthy'? _markerImageUrl: _unhealthyMarkerImageUrl);//TODO: Filter based on label
105 |
106 | markers.add(
107 | MapMarker(
108 | id: i.toString(),
109 | position: markerLocation,
110 | icon: markerImage,
111 | ),
112 | );
113 | }
114 | }
115 |
116 | _clusterManager = await MapHelper.initClusterManager(
117 | markers,
118 | _minClusterZoom,
119 | _maxClusterZoom,
120 | );
121 |
122 | await _updateMarkers();
123 | }
124 |
125 | /// Gets the markers and clusters to be displayed on the map for the current zoom level and
126 | /// updates state.
127 | Future _updateMarkers([double updatedZoom]) async {
128 | if (_clusterManager == null || updatedZoom == _currentZoom) return;
129 |
130 | if (updatedZoom != null) {
131 | _currentZoom = updatedZoom;
132 | }
133 |
134 | setState(() {
135 | _areMarkersLoading = true;
136 | });
137 |
138 | final updatedMarkers = await MapHelper.getClusterMarkers(
139 | _clusterManager,
140 | _currentZoom,
141 | _clusterColor,
142 | _clusterTextColor,
143 | 80,
144 | );
145 |
146 | _markers
147 | ..clear()
148 | ..addAll(updatedMarkers);
149 |
150 | setState(() {
151 | _areMarkersLoading = false;
152 | });
153 | }
154 |
155 | @override
156 | Widget build(BuildContext context) {
157 | return Scaffold(
158 | // appBar: AppBar(
159 | // title: Text('Map Page'),
160 | // ),
161 | body: Stack(
162 | children: [
163 | // Google Map widget
164 | Opacity(
165 | opacity: _isMapLoading ? 0 : 1,
166 | child: GoogleMap(
167 | mapToolbarEnabled: false,
168 | initialCameraPosition: CameraPosition(
169 | target: LatLng(41.143029, -8.611274),
170 | zoom: _currentZoom,
171 | ),
172 | markers: _markers,
173 | onMapCreated: (controller) => _onMapCreated(controller),
174 | onCameraMove: (position) => _updateMarkers(position.zoom),
175 | ),
176 | ),
177 |
178 | // Map loading indicator
179 | Opacity(
180 | opacity: _isMapLoading ? 1 : 0,
181 | child: Center(child: CircularProgressIndicator()),
182 | ),
183 |
184 | // Map markers loading indicator
185 | if (_areMarkersLoading)
186 | Padding(
187 | padding: const EdgeInsets.all(8.0),
188 | child: Align(
189 | alignment: Alignment.topCenter,
190 | child: Card(
191 | elevation: 2,
192 | color: Colors.grey.withOpacity(0.9),
193 | child: Padding(
194 | padding: const EdgeInsets.all(4),
195 | child: Text(
196 | 'Loading',
197 | style: TextStyle(color: Colors.white),
198 | ),
199 | ),
200 | ),
201 | ),
202 | ),
203 | ],
204 | ),
205 | floatingActionButtonLocation: FloatingActionButtonLocation.startFloat,
206 | floatingActionButtonAnimator: FloatingActionButtonAnimator.scaling,
207 | floatingActionButton: FloatingActionButton(
208 | heroTag: 'fab',
209 | onPressed: () {
210 | Navigator.of(context).pop();
211 | },
212 | elevation: 5.0,
213 | tooltip: "Go back",
214 | child: Icon(Icons.arrow_back),
215 | ),
216 | );
217 | }
218 | }
219 |
--------------------------------------------------------------------------------
/lib/pages/pages_export.dart:
--------------------------------------------------------------------------------
1 | export 'home_page.dart';
2 | export 'controls_page.dart';
3 | export 'report_page.dart';
--------------------------------------------------------------------------------
/lib/pages/process_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 | import 'dart:math';
4 | import 'dart:ui';
5 | import 'package:cloud_firestore/cloud_firestore.dart';
6 | import 'package:firebase_ml_custom/firebase_ml_custom.dart';
7 | import 'package:firebase_storage/firebase_storage.dart';
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter/services.dart';
10 | import 'package:sign_in/commons/animated_popup.dart';
11 | import 'package:sign_in/models/user.dart';
12 | import 'package:tflite/tflite.dart';
13 | import 'package:path_provider/path_provider.dart';
14 | import 'package:http/http.dart' as http;
15 |
16 | class ProcessingPage extends StatefulWidget {
17 | @override
18 | _ProcessingPageState createState() => _ProcessingPageState();
19 | }
20 |
21 | class _ProcessingPageState extends State {
22 | final _firestore = Firestore.instance;
23 | final _storage = FirebaseStorage.instance;
24 | String _loaded;
25 | List _imgUrls = [];
26 | List _images;
27 | List> _labels = [];
28 | bool _isLoaded = false;
29 | String _currImg =
30 | 'https://www.generationsforpeace.org/wp-content/uploads/2018/03/empty.jpg';
31 |
32 | Future loadModel() async {
33 | final modelFile = await loadModelFromFirebase();
34 | _loaded = await loadTFLiteModel(modelFile);
35 | print(_loaded);
36 | }
37 |
38 | /// Downloads custom model from the Firebase console and return its file.
39 | /// located on the mobile device.
40 | static Future loadModelFromFirebase() async {
41 | try {
42 | // Create model with a name that is specified in the Firebase console
43 | final model = FirebaseCustomRemoteModel('TomatoModel');
44 |
45 | // Specify conditions when the model can be downloaded.
46 | // If there is no wifi access when the app is started,
47 | // this app will continue loading until the conditions are satisfied.
48 | final conditions = FirebaseModelDownloadConditions(
49 | androidRequireWifi: true,
50 | iosAllowCellularAccess: false,
51 | iosAllowBackgroundDownloading: true,
52 | androidRequireDeviceIdle: false,
53 | );
54 |
55 | // Create model manager associated with default Firebase App instance.
56 | final modelManager = FirebaseModelManager.instance;
57 |
58 | // Begin downloading and wait until the model is downloaded successfully.
59 | await modelManager.download(model, conditions);
60 | assert(await modelManager.isModelDownloaded(model) == true);
61 |
62 | // Get latest model file to use it for inference by the interpreter.
63 | var modelFile = await modelManager.getLatestModelFile(model);
64 | assert(modelFile != null);
65 | return modelFile;
66 | } catch (exception) {
67 | print('Failed on loading your model from Firebase: $exception');
68 | print('The program will not be resumed');
69 | rethrow;
70 | }
71 | }
72 |
73 | /// Loads the model into some TF Lite interpreter.
74 | /// In this case interpreter provided by tflite plugin.
75 | static Future loadTFLiteModel(File modelFile) async {
76 | try {
77 | final appDirectory = await getApplicationDocumentsDirectory();
78 | final labelsData = await rootBundle.load("assets/TomatoModel.txt");
79 | final labelsFile = await File(appDirectory.path + "/TomatoModel.txt")
80 | .writeAsBytes(labelsData.buffer
81 | .asUint8List(labelsData.offsetInBytes, labelsData.lengthInBytes));
82 |
83 | assert(await Tflite.loadModel(
84 | model: modelFile.path,
85 | labels: labelsFile.path,
86 | isAsset: false,
87 | ) ==
88 | "success");
89 | return "Model is loaded";
90 | } catch (exception) {
91 | print(
92 | 'Failed on loading your model to the TFLite interpreter: $exception');
93 | print('The program will not be resumed');
94 | rethrow;
95 | }
96 | }
97 |
98 | Future> getImages() async {
99 | DocumentSnapshot doc = await _firestore
100 | .collection('users')
101 | .document('HHJjcEassOW3nRJEE65tYXmTJzn2')
102 | .get();
103 | // print(doc.data['urls'].length);
104 | _imgUrls = doc.data['urls'];
105 | return doc.data['urls'];
106 | }
107 |
108 | Future urlToFile(String imageUrl) async {
109 | // generate random number.
110 | var rng = new Random();
111 | // get temporary directory of device.
112 | Directory tempDir = await getTemporaryDirectory();
113 | // get temporary path from temporary directory.
114 | String tempPath = tempDir.path;
115 | // create a new file in temporary path with random file name.
116 | File file = new File('$tempPath' + (rng.nextInt(100)).toString() + '.png');
117 | print('$tempPath' + (rng.nextInt(100)).toString() + '.png');
118 | // call http.get method and pass imageUrl into it to get response.
119 | http.Response response = await http.get(imageUrl);
120 | // write bodyBytes received in response to file.
121 | await file.writeAsBytes(response.bodyBytes);
122 | // now return the file which is created with random name in
123 | // temporary directory and image bytes from response is written to // that file.
124 | return file;
125 | }
126 |
127 | Future> getImageLabels(File img) async {
128 | try {
129 | final image = img;
130 | if (image == null) {
131 | return null;
132 | }
133 |
134 | var labels = List