diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies new file mode 100644 index 0000000000000000000000000000000000000000..52b1c6a03a93b4d2cbdeb35281f7e486aaa86feb --- /dev/null +++ b/.flutter-plugins-dependencies @@ -0,0 +1 @@ +{"_info":"// This is a generated file; do not edit or check into version control.","dependencyGraph":[{"name":"flutter_plugin_android_lifecycle","dependencies":[]},{"name":"google_maps_flutter","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"location","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_macos"]},{"name":"path_provider_macos","dependencies":[]}]} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..a1b47e53bf30b0552bf6204186dc275a0899c63b --- /dev/null +++ b/.gitignore @@ -0,0 +1,293 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# Visual Studio Code related +.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.packages +.pub-cache/ +.pub/ +build/ + +# Android related +**/android/**/gradle-wrapper.jar +**/android/.gradle +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages + +env-*/ + + +# Created by https://www.gitignore.io/api/linux,django,python,pycharm+all +# Edit at https://www.gitignore.io/?templates=linux,django,python,pycharm+all + +### Django ### + + +# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/ +# in your Git repository. Update and uncomment the following line accordingly. +# /staticfiles/ + +### Django.Python Stack ### +# Byte-compiled / optimized / DLL files + + +# Distribution / packaging + + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. + + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +.hypothesis/ +.pytest_cache/ +coverage/ + +# Translations +*.mo + +# Django stuff: + +# Flask stuff: + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings + + +# mkdocs documentation +/site + +# mypy +# Pyre type checker +.pyre/ + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### PyCharm+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### PyCharm+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin + .idea/sonarlint + +### Python ### +# Byte-compiled / optimized / DLL files + +# C extensions + +# Distribution / packaging + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. + +# Installer logs + +# Unit test / coverage reports + +# Translations + +# Django stuff: + +# Flask stuff: + +# Scrapy stuff: + +# Sphinx documentation + +# PyBuilder + +# Jupyter Notebook + +# IPython + +# pyenv + +# celery beat schedule file + +# SageMath parsed files + +# Environments + +# Spyder project settings + +# Rope project settings + +# mkdocs documentation + +# mypy + +# Pyre type checker + +### Python Patch ### +.venv/ + +# End of https://www.gitignore.io/api/linux,django,python,pycharm+all + +tests.output + +.flutter-plugins-dependencies diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..da9a47c7190313948d82edb935b54ebcdf895416 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,123 @@ +stages: + - lint + - test + - sonarqube + - deploy + +variables: + APP_NAME: "bisaGo" + +before_script: + - export PATH=$PATH:/sdk/android-sdk-linux/platform-tools/ + - echo flutter.sdk=/sdk/flutter > android/local.properties + - flutter pub get + +image: michael09/flutter:latest + +Lint: + stage: lint + script: + - flutter analyze + +Test: + stage: test + script: + - flutter test --coverage + - flutter test --machine > tests.output + - lcov --summary coverage/lcov.info + - genhtml coverage/lcov.info --output=coverage + artifacts: + expire_in: 1 hour + paths: + - coverage/lcov.info + - tests.output + +Sonarqube: + dependencies: + - Test + stage: sonarqube + before_script: + - export PATH=$PATH:/sdk/flutter/bin/cache/dart-sdk/bin + - flutter pub get + script: + - sonar-scanner -Dsonar.login=$SONARQUBE_TOKEN -Dsonar.branch.name=$CI_COMMIT_REF_NAME -Dsonar.projectKey=$SONARQUBE_PROJECT_KEY -X + + +DeployToProduction: + variables: + ENV_NAME: "production" + + image: runmymind/docker-android-sdk:latest + stage: deploy + tags: + - build + only: + refs: + - master + before_script: + - wget --quiet --output-document=flutter.tar.xz https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.12.13+hotfix.7-stable.tar.xz && tar xf flutter.tar.xz -C / + - export PATH=$PATH:/flutter/bin + - apt-get update && apt-get install gnupg -y + - curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt-get install -y nodejs + - flutter doctor -v + - flutter packages get + - npm install --global appcenter-cli + script: + - flutter build apk --release --build-name=$APP_NAME --build-number=1 + - appcenter + - appcenter login --token=$APPCENTER_API_TOKEN + - appcenter distribute release -f build/app/outputs/apk/release/app-release.apk --app $APPCENTER_APP_NAME_PROD --group $APPCENTER_GROUP_TARGET + environment: + name: production + +DeployToStaging: + variables: + ENV_NAME: "staging" + image: runmymind/docker-android-sdk:latest + stage: deploy + tags: + - build + only: + refs: + - staging + before_script: + - wget --quiet --output-document=flutter.tar.xz https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.12.13+hotfix.8-stable.tar.xz && tar xf flutter.tar.xz -C / + - export PATH=$PATH:/flutter/bin + - apt-get update && apt-get install gnupg -y + - curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt-get install -y nodejs + - flutter doctor -v + - flutter packages get + - npm install --global appcenter-cli + script: + - flutter build apk --release --build-name=$APP_NAME-$ENV_NAME --build-number=1 + - appcenter + - appcenter login --token=$APPCENTER_API_TOKEN + - appcenter distribute release -f build/app/outputs/apk/release/app-release.apk --app $APPCENTER_APP_NAME_STAGING --group $APPCENTER_GROUP_TARGET + environment: + name: staging + +DeployToDevelopment: + variables: + ENV_NAME: "development" + image: runmymind/docker-android-sdk:latest + stage: deploy + tags: + - build + only: + refs: + - /^US-.*$/ + before_script: + - wget --quiet --output-document=flutter.tar.xz https://storage.googleapis.com/flutter_infra/releases/stable/linux/flutter_linux_v1.12.13+hotfix.8-stable.tar.xz && tar xf flutter.tar.xz -C / + - export PATH=$PATH:/flutter/bin + - apt-get update && apt-get install gnupg -y + - curl -sL https://deb.nodesource.com/setup_12.x | bash - && apt-get install -y nodejs + - flutter doctor -v + - flutter packages get + - npm install --global appcenter-cli + script: + - flutter build apk --release --build-name=$APP_NAME-$ENV_NAME --build-number=1 + - appcenter + - appcenter login --token=$APPCENTER_API_TOKEN + - appcenter distribute release -f build/app/outputs/apk/release/app-release.apk --app $APPCENTER_APP_NAME_DEV --group $APPCENTER_GROUP_TARGET + environment: + name: development \ No newline at end of file diff --git a/README.md b/README.md index 11115a74aaeb37a3c29ede946d67decef504ed0f..6c0f425d264c9e29e46a7929166d7d3cb77bf6c3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,66 @@ -# PPLapangan Tembak-DTB Layanan Siswa Disabilitas +# PPLapangan Tembak & PoiPoLe - DTB Layanan Siswa Disabilitas (Front End) - bisaGo +Code Coverage +-------------- +[![coverage report](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2020/ppl-c/dtb-beasiswa-miskin-dan-disabilitas/pplapangan-tembak-dtb-layanan-siswa-disabilitas/badges/staging/coverage.svg?job=Test)](https://gitlab.cs.ui.ac.id/ppl-fasilkom-ui/2020/ppl-c/dtb-beasiswa-miskin-dan-disabilitas/pplapangan-tembak-dtb-layanan-siswa-disabilitas/commits/staging) + +>bisaGo is a mobile application made with Flutter and Django REST API to gather information from users about disability friendly facilities. + +## Developers + +PPLapanganTembak +1. [Adzkia Aisyah Afrah Hardian](https://gitlab.cs.ui.ac.id/adzkia.aisyah) +2. [Agnes Handoko](https://gitlab.cs.ui.ac.id/agneshandoko) +3. [Fakhira Devina](https://gitlab.cs.ui.ac.id/hiradevina) +4. [Faza Siti Sabira Prakoso](https://gitlab.cs.ui.ac.id/fazasabirappl) +5. [Firriyal bin Yahya](https://gitlab.cs.ui.ac.id/feriyalbinyahya) + +PoiPoLeGan +1. [Bimo Iman Smartadi](https://gitlab.cs.ui.ac.id/bimo.iman) +2. [Bayukanta Iqbal Gunawan](https://gitlab.cs.ui.ac.id/Bayukanta) +3. [Dzaky Noor Hasyim](https://gitlab.cs.ui.ac.id/NoorHasyim) +4. [Muhammad Abdurrahman](https://gitlab.cs.ui.ac.id/muhammad.abdurrahman71) +5. [Usman Sidiq](https://gitlab.cs.ui.ac.id/usman.sidiq71) + + + +## Table of Content + +* Install +* Running Development Mode + +## Install +The front end side uses Flutter, for installing please head to the [official documentation of Flutter](https://flutter.dev/docs/get-started/install) + +Make sure you already installed everything to work with Flutter with command: +```bash +flutter doctor -v +``` + +Install all the package dependencies in `pubspec.yaml` +```bash +flutter pub get +``` +Get your [Maps API Key](https://developers.google.com/maps/documentation/android-sdk/get-api-key) and put the key on `android/local.properties` +```bash +MAPS_API_KEY=Bu*************** +``` + +## Running Development Mode +Run the app using the development flavor +```bash +flutter run -t lib/main_dev.dart +``` +## Building Models with JsonSerializable +Jadi abis get dari API, jsonnya di map ke models biar rapih. +1. Tulis ada field apa aja dari jsonnya (bisa liat contoh yang di models/lokasi.dart) +2. bagian 'part of {nama models}.g.dart' itu harus ditulis di model yg mau dibuat. di awal emang merah, tapi biarin aja +3. kalo semua field udah di tulis, run +```bash +flutter pub run build_runner build +``` +4. nanti akan ke build file {nama models}.g.dart, yang di nomor 2 merah harusnya udah gak merah lagi + +## Passing Data with BLoC +Udah ada contohnya di /bloc (implementasi di screen nya ada di page/pencarian/pencarian.dart) +Bisa baca [disini]https://itnext.io/flutter-handling-your-network-api-calls-like-a-boss-936eef296547 sebagai panduannya \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..5246b3eccb66a25b9f81e3d3f65636a86a444e8e --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,5 @@ +include: package:pedantic/analysis_options.yaml + +analyzer: + exclude: + - "**/*.g.dart" \ No newline at end of file diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..bc2100d8f75e6efef413729756e448e910f7304d --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,7 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java diff --git a/android/.project b/android/.project new file mode 100644 index 0000000000000000000000000000000000000000..3964dd3f5b7fea7ecf391254ba292fcfe96bb513 --- /dev/null +++ b/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/android/.settings/org.eclipse.buildship.core.prefs b/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..e8895216fd3c0c3af4c4522334775f41b7deb42e --- /dev/null +++ b/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/android/app/.classpath b/android/app/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..eb19361b5711e614b090eac2f1b51309da2ec1e4 --- /dev/null +++ b/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/android/app/.project b/android/app/.project new file mode 100644 index 0000000000000000000000000000000000000000..ac485d7c3e627d997f59da65ac961160079a0143 --- /dev/null +++ b/android/app/.project @@ -0,0 +1,23 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/android/app/.settings/org.eclipse.buildship.core.prefs b/android/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..b1886adb46c085de842f1283c1a3c25151bfc988 --- /dev/null +++ b/android/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..191a87db47db43b4c6e8ddf24d24a53afb03aa97 --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,72 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +def localPropertyApiToken = localProperties.getProperty("MAPS_API_KEY") +def systemEnvApiToken = System.getenv('MAPS_API_KEY') + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" +def MAPS_API_KEY = localPropertyApiToken != null ? localPropertyApiToken : systemEnvApiToken + +android { + compileSdkVersion 28 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.ppl_disabilitas" + minSdkVersion 16 + targetSdkVersion 28 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + manifestPlaceholders = [MAPS_API_KEY: MAPS_API_KEY] + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so flutter run --release works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' +} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..eac51190b63296f719b720b468a0f4f39846afba --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,8 @@ + + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..6782f488f66280a2a535ddcd63842c11e2fdde0b --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/example/ppl_disabilitas/MainActivity.kt b/android/app/src/main/kotlin/com/example/ppl_disabilitas/MainActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..835715ce556daf4ad5db3a00014ffeb139e77868 --- /dev/null +++ b/android/app/src/main/kotlin/com/example/ppl_disabilitas/MainActivity.kt @@ -0,0 +1,12 @@ +package com.example.ppl_disabilitas + +import androidx.annotation.NonNull; +import io.flutter.embedding.android.FlutterActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugins.GeneratedPluginRegistrant + +class MainActivity: FlutterActivity() { + override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) { + GeneratedPluginRegistrant.registerWith(flutterEngine); + } +} diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000000000000000000000000000000000000..304732f8842013497e14bd02f67a55f2614fb8f7 --- /dev/null +++ b/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..77d7fa183cfe94bec5e53f3f8f634ff1ef422884 Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..c83fa7614bc85964ca364e966dda34f61fa97248 Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..09d4391482be68e9e4a07fab769b5de337d16eb1 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a31c0801ba39b64f67346a05c88aee3681541bb3 Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..efec05dd687ab7ebc29c34da5270650ca42d2812 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..214f1299f3e68381d9db562d339fd6648d8f7892 Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000000000000000000000000000000000000..00fa4417cfbef8673c47c86eb24033fcd97056a8 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..38838990d69858f983edbee6e8acf5a32c10ef0a --- /dev/null +++ b/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/build.gradle b/android/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..6f110de1f2998db83a12f1904667881a7f470604 --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,31 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.google.gms:google-services:4.2.0' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..28276e2ce4a982395bef4f2ee1878f64cc6f0f42 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,7 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true +android.enableJetifier=true +android.useAndroidX=true +org.gradle.jvmargs=-Xmx1536M diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..63ab3ae08f9e4c3ddbbac64e0c3aadee390f7c22 --- /dev/null +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..5a2f14fb18f6e8b8c4308ff0f0dc187d9d27a5aa --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/android/settings_aar.gradle b/android/settings_aar.gradle new file mode 100644 index 0000000000000000000000000000000000000000..e7b4def49cb53d9aa04228dd3edb14c9e635e003 --- /dev/null +++ b/android/settings_aar.gradle @@ -0,0 +1 @@ +include ':app' diff --git a/assets/fonts/Comfortaa-Bold.ttf b/assets/fonts/Comfortaa-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4600581103f0d08d17bcf21e971034cf3ad5662f Binary files /dev/null and b/assets/fonts/Comfortaa-Bold.ttf differ diff --git a/assets/fonts/Comfortaa-Light.ttf b/assets/fonts/Comfortaa-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..216f8d18b6807e70533b9dcbf53c3ee78245ea4a Binary files /dev/null and b/assets/fonts/Comfortaa-Light.ttf differ diff --git a/assets/fonts/Comfortaa-Medium.ttf b/assets/fonts/Comfortaa-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c1f37feffc83f0abe0273bba37cc22233333ecee Binary files /dev/null and b/assets/fonts/Comfortaa-Medium.ttf differ diff --git a/assets/fonts/Comfortaa-Regular.ttf b/assets/fonts/Comfortaa-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6dd1f3ae3e66aa6b9d7532d879aa8810ca6d76f7 Binary files /dev/null and b/assets/fonts/Comfortaa-Regular.ttf differ diff --git a/assets/fonts/Comfortaa-SemiBold.ttf b/assets/fonts/Comfortaa-SemiBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..faa8f5c21708d5bd73acbb600ece13f22ececc09 Binary files /dev/null and b/assets/fonts/Comfortaa-SemiBold.ttf differ diff --git a/assets/fonts/Muli-Black.ttf b/assets/fonts/Muli-Black.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ccdfdc1d1a9b64e5011d9899bccbf270983740b1 Binary files /dev/null and b/assets/fonts/Muli-Black.ttf differ diff --git a/assets/fonts/Muli-BlackItalic.ttf b/assets/fonts/Muli-BlackItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..b7b13d1c1f982ffb504ee810b6284b3a3c6c0c06 Binary files /dev/null and b/assets/fonts/Muli-BlackItalic.ttf differ diff --git a/assets/fonts/Muli-Bold.ttf b/assets/fonts/Muli-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..93831397ab7720248d9d27db1f6dd6ae96192a14 Binary files /dev/null and b/assets/fonts/Muli-Bold.ttf differ diff --git a/assets/fonts/Muli-BoldItalic.ttf b/assets/fonts/Muli-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..111b7465f9713d57330eb72b353a2c1400ff6828 Binary files /dev/null and b/assets/fonts/Muli-BoldItalic.ttf differ diff --git a/assets/fonts/Muli-ExtraLight.ttf b/assets/fonts/Muli-ExtraLight.ttf new file mode 100644 index 0000000000000000000000000000000000000000..2fcaa704c757298b9ca696dc45647f1c9ee5d310 Binary files /dev/null and b/assets/fonts/Muli-ExtraLight.ttf differ diff --git a/assets/fonts/Muli-ExtraLightItalic.ttf b/assets/fonts/Muli-ExtraLightItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d19efcd00ef1e9ef5afad3756ef54adf58e0086d Binary files /dev/null and b/assets/fonts/Muli-ExtraLightItalic.ttf differ diff --git a/assets/fonts/Muli-Italic.ttf b/assets/fonts/Muli-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..207ab18929699d83e6fcf01db4c0ee7727f8647b Binary files /dev/null and b/assets/fonts/Muli-Italic.ttf differ diff --git a/assets/fonts/Muli-Light.ttf b/assets/fonts/Muli-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6bd6c60b5043877048b9f8b852060028ccb98e17 Binary files /dev/null and b/assets/fonts/Muli-Light.ttf differ diff --git a/assets/fonts/Muli-LightItalic.ttf b/assets/fonts/Muli-LightItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..d2af065bb2c8bb635f3edf357de02de0d6c4ee9e Binary files /dev/null and b/assets/fonts/Muli-LightItalic.ttf differ diff --git a/assets/fonts/Muli-Medium.ttf b/assets/fonts/Muli-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f28c094c309d4464c7c8b85309ee7b414a6d4a10 Binary files /dev/null and b/assets/fonts/Muli-Medium.ttf differ diff --git a/assets/fonts/Muli-MediumItalic.ttf b/assets/fonts/Muli-MediumItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..06eb9ae773aef6d699a8bb24068cbc21bafc134e Binary files /dev/null and b/assets/fonts/Muli-MediumItalic.ttf differ diff --git a/assets/fonts/Muli-Regular.ttf b/assets/fonts/Muli-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..9776a3e4b31d084ade38c3d1fd2767a56961cc97 Binary files /dev/null and b/assets/fonts/Muli-Regular.ttf differ diff --git a/assets/fonts/Muli-SemiBold.ttf b/assets/fonts/Muli-SemiBold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..86d5ecc6c727ddecc341dafe79fbd400dcdccf91 Binary files /dev/null and b/assets/fonts/Muli-SemiBold.ttf differ diff --git a/assets/fonts/Muli-SemiBoldItalic.ttf b/assets/fonts/Muli-SemiBoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..61889136b1c4bfbd42258e919280cb52eb23ba42 Binary files /dev/null and b/assets/fonts/Muli-SemiBoldItalic.ttf differ diff --git a/assets/icon/2x/current_loc.png b/assets/icon/2x/current_loc.png new file mode 100644 index 0000000000000000000000000000000000000000..1c55a3058fc5c1429bac6949380435d055b2c689 Binary files /dev/null and b/assets/icon/2x/current_loc.png differ diff --git a/assets/icon/2x/icon_launcher.png b/assets/icon/2x/icon_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..2c188192f166ed99579ec79c664074e12fd25e99 Binary files /dev/null and b/assets/icon/2x/icon_launcher.png differ diff --git a/assets/icon/3x/current_loc.png b/assets/icon/3x/current_loc.png new file mode 100644 index 0000000000000000000000000000000000000000..930d897dceee528d3c2b13135718a712246099f8 Binary files /dev/null and b/assets/icon/3x/current_loc.png differ diff --git a/assets/icon/3x/icon_launcher.png b/assets/icon/3x/icon_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..cf5be9783e1ab2b8561990ea143d0082d4183eb8 Binary files /dev/null and b/assets/icon/3x/icon_launcher.png differ diff --git a/assets/icon/current_loc.png b/assets/icon/current_loc.png new file mode 100644 index 0000000000000000000000000000000000000000..08fc2db183a39b330b1526f39c681d9518b67539 Binary files /dev/null and b/assets/icon/current_loc.png differ diff --git a/assets/icon/icon_launcher.png b/assets/icon/icon_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..7c82fa986afdb49514350a6e24dbb1998727f9be Binary files /dev/null and b/assets/icon/icon_launcher.png differ diff --git a/assets/icon/loc.png b/assets/icon/loc.png new file mode 100644 index 0000000000000000000000000000000000000000..a7c8787a3af5b53f89978d11d8af32d2a032697f Binary files /dev/null and b/assets/icon/loc.png differ diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e96ef602b8d172f7cd28ba656aac097f741c736d --- /dev/null +++ b/ios/.gitignore @@ -0,0 +1,32 @@ +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000000000000000000000000000000000000..6b4c0f78a7850094f62713858e533a2fc8eda617 --- /dev/null +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000000000000000000000000000000000000..e8efba114687be7d0e4e5d026a31f5efd04d20bf --- /dev/null +++ b/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000000000000000000000000000000000000..399e9340e6f617f68676161ad4a64edcbe483115 --- /dev/null +++ b/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000000000000000000000000000000000000..b30a428b5e77ede0fd1d2cb7009f930e42d8def1 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,90 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '9.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def parse_KV_file(file, separator='=') + file_abs_path = File.expand_path(file) + if !File.exists? file_abs_path + return []; + end + generated_key_values = {} + skip_line_start_symbols = ["#", "/"] + File.foreach(file_abs_path) do |line| + next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } + plugin = line.split(pattern=separator) + if plugin.length == 2 + podname = plugin[0].strip() + path = plugin[1].strip() + podpath = File.expand_path("#{path}", file_abs_path) + generated_key_values[podname] = podpath + else + puts "Invalid plugin specification: #{line}" + end + end + generated_key_values +end + +target 'Runner' do + use_frameworks! + use_modular_headers! + + # Flutter Pod + + copied_flutter_dir = File.join(__dir__, 'Flutter') + copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework') + copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec') + unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path) + # Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet. + # That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration. + # CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist. + + generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig') + unless File.exist?(generated_xcode_build_settings_path) + raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path) + cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR']; + + unless File.exist?(copied_framework_path) + FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir) + end + unless File.exist?(copied_podspec_path) + FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir) + end + end + + # Keep pod path relative so it can be checked into Podfile.lock. + pod 'Flutter', :path => 'Flutter' + + # Plugin Pods + + # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock + # referring to absolute paths on developers' machines. + system('rm -rf .symlinks') + system('mkdir -p .symlinks/plugins') + plugin_pods = parse_KV_file('../.flutter-plugins') + plugin_pods.each do |name, path| + symlink = File.join('.symlinks', 'plugins', name) + File.symlink(path, symlink) + pod name, :path => File.join(symlink, 'ios') + end +end + +# Prevent Cocoapods from embedding a second Flutter framework and causing an error with the new Xcode build system. +install! 'cocoapods', :disable_input_output_paths => true + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'NO' + end + end +end diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000000000000000000000000000000000000..e6fbe067943bc4bdfa163df12b63f83ad2c499ee --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,600 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + A713680F956827CC800E5882 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 608DBD9F25B5A1E158194D12 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 27B4326A6F124C13099D180A /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 608DBD9F25B5A1E158194D12 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 94561A220A1B4EFA7831E0FC /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F7D6823AE5698B88142C285E /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + A713680F956827CC800E5882 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 829932E47EADAEFD209551C7 /* Pods */ = { + isa = PBXGroup; + children = ( + 94561A220A1B4EFA7831E0FC /* Pods-Runner.debug.xcconfig */, + F7D6823AE5698B88142C285E /* Pods-Runner.release.xcconfig */, + 27B4326A6F124C13099D180A /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 829932E47EADAEFD209551C7 /* Pods */, + F0491B426155A7C9E1ADB1A7 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + ); + name = "Supporting Files"; + sourceTree = ""; + }; + F0491B426155A7C9E1ADB1A7 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 608DBD9F25B5A1E158194D12 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 45875E25277A3BB7443A1483 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + A6A877344DE185CEA8904842 /* [CP] Embed Pods Frameworks */, + 17BFDE4BCED4D29A440D5CB6 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 17BFDE4BCED4D29A440D5CB6 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 45875E25277A3BB7443A1483 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + A6A877344DE185CEA8904842 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.pplDisabilitas; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.pplDisabilitas; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.pplDisabilitas; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..1d526a16ed0f1cd0c2409d848bf489b93fefa3b2 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000000000000000000000000000000000000..18d981003d68d0546c4804ac2ff47dd97c6e7921 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000000000000000000000000000000000000..a28140cfdb3ff9b7a11a9497b84546d615db2afa --- /dev/null +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000000000000000000000000000000000000..21a3cc14c74e969ab1548274a8512ebfecc40f78 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000000000000000000000000000000000000..70693e4a8c128fc4350b157416374ca599ac8c7b --- /dev/null +++ b/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..d36b1fab2d9dea668a4f83df94d525897d9e68dd --- /dev/null +++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..300ae2f80ad2814cc466704e147c06059e78e345 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..ada4b7fe4d79380d3e1dae5a73fc2fee19c833a7 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8eea4dd22c0f64e7e2e729c1bf4429e382c01287 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9d8723cce631060e3706563d92eed7a599334f5e Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..1eacd7844cd572c44122b00b633ff674b09f3ced Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d7c6ebbeb3447d068bc1740d810dc31400202935 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..11656b43ffd81643db2f44232753f5734558448c Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..8eea4dd22c0f64e7e2e729c1bf4429e382c01287 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..b23aabf9ee96e2e82b91c7cd3b8af95e39079d59 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..7bb01ba0916c018d6b493da8b33167bed53a08b1 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..2dbb06f0c78bc1d593744c560c79a902218b7ab5 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a2cc47629e4fc439af429f37995d8fa3785f3ece Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..e292b43465108f58c1c77f37bd77be4967009a33 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d877aba55fc7f9500f2377807f4b55dee73974d3 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..7bb01ba0916c018d6b493da8b33167bed53a08b1 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e35743855f7dd22f7aba64ae49f5fd72bb0e7c45 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..77d7fa183cfe94bec5e53f3f8f634ff1ef422884 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..efec05dd687ab7ebc29c34da5270650ca42d2812 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..4dbd42d651705769af62603611dfccc3b46cb768 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..837710082fe7d5b9a57fbcfe87c56b999a8893a3 Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d67bc9485fe151a679841955dc61a110f4f37e0d Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000000000000000000000000000000000000..0bedcf2fd46788ae3a01a423467513ff59b5c120 --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "LaunchImage.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "LaunchImage@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000000000000000000000000000000000000..89c2725b70f1882be97f5214fafe22d27a0ec01e --- /dev/null +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000000000000000000000000000000000000..f2e259c7c9390ff69a6bbe1e0907e6dc366848e7 --- /dev/null +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000000000000000000000000000000000000..f3c28516fb38e64d88cfcf5fb1791175df078f2f --- /dev/null +++ b/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist new file mode 100644 index 0000000000000000000000000000000000000000..a59339f96fd8e242ff675f7614e9e0694560cf00 --- /dev/null +++ b/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ppl_disabilitas + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000000000000000000000000000000000000..7335fdf9000cec1b6c1e3f506b196734e8a427ff --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" \ No newline at end of file diff --git a/lib/app.dart b/lib/app.dart new file mode 100644 index 0000000000000000000000000000000000000000..f5a00dfb9b5822c8be96289a04ace48f9c1df934 --- /dev/null +++ b/lib/app.dart @@ -0,0 +1,16 @@ +import 'package:flutter/material.dart'; +import 'package:ppl_disabilitas/page/dashboard/dashboard.dart'; + +class BisaGo extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'bisaGo', + theme: ThemeData( + fontFamily: 'Muli', + backgroundColor: Colors.white, + ), + home: Dashboard(), + ); + } +} diff --git a/lib/bloc/LokasiResponseBloc.dart b/lib/bloc/LokasiResponseBloc.dart new file mode 100644 index 0000000000000000000000000000000000000000..e9266e95fe9a66acc34ec1d22e631772bf9c51a6 --- /dev/null +++ b/lib/bloc/LokasiResponseBloc.dart @@ -0,0 +1,64 @@ +import 'dart:async'; + +import 'package:ppl_disabilitas/model/lokasi.dart'; +import 'package:ppl_disabilitas/network/data/network_model.dart'; +import 'package:ppl_disabilitas/repository/LokasiRepository.dart'; + +class LokasiResponseBloc { + StreamController _recentSearchController; + LokasiRepository _lokasiRepository; + StreamController _lokasiListController; + + StreamSink> get recentSearchSink => + _recentSearchController.sink; + Stream> get recentSearchStream => + _recentSearchController.stream; + + StreamSink> get lokasiListSink => + _lokasiListController.sink; + Stream> get lokasiListStream => + _lokasiListController.stream; + + LokasiResponseBloc() { + _lokasiListController = + StreamController>(); + _recentSearchController = StreamController>(); + _lokasiRepository = LokasiRepository(); + fetchLokasiList(); + fetchRecentSearch(); + } + + fetchLokasiList() async { + lokasiListSink.add(NetworkModel.loading('Getting Locations')); + try { + LokasiListResponse lokasiListResponse = + await _lokasiRepository.fetchLokasi(); + print("lokasi list response: $lokasiListResponse"); + lokasiListSink.add(NetworkModel.completed(lokasiListResponse)); + } catch (e) { + lokasiListSink.add(NetworkModel.error(e.toString())); + print("$e"); + } + } + + fetchRecentSearch() async { + recentSearchSink.add(NetworkModel.loading('Getting Recent Search')); + try { + LokasiListResponse recentSearchData = await _lokasiRepository.fetchRecentSearch(); + print("recentSearchData ${recentSearchData.listLokasi}"); + recentSearchSink.add(NetworkModel.completed(recentSearchData)); + } catch (e) { + recentSearchSink.add(NetworkModel.error(e.toString())); + print("line 53 ${e.toString()}"); + } + } + + saveRecentSearch(Lokasi search) async { + await _lokasiRepository.saveRecentSearch(search); + } + + dispose() { + _recentSearchController?.close(); + _lokasiListController?.close(); + } +} diff --git a/lib/component/bisago_appbar.dart b/lib/component/bisago_appbar.dart new file mode 100644 index 0000000000000000000000000000000000000000..e32af12651aae7289ffd82946141b165098d1465 --- /dev/null +++ b/lib/component/bisago_appbar.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:ppl_disabilitas/config/styles.dart'; + +class BisaGoAppBar extends StatelessWidget implements PreferredSizeWidget { + @override + final Size preferredSize = Size.fromHeight(55); + @override + Widget build(BuildContext context) { + return AppBar( + elevation: 15, + centerTitle: true, + backgroundColor: greenPrimary, + title: Row( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Padding(padding: EdgeInsets.all(doubleSpace), + child: Text( + "bisaGo", + style: TextStyle( + fontSize: 25, + fontFamily: 'Comfortaa', + fontWeight: FontWeight.w800), + ),) + + ], + ), + ); + } +} diff --git a/lib/component/bisago_drawer.dart b/lib/component/bisago_drawer.dart new file mode 100644 index 0000000000000000000000000000000000000000..ff510da5af717d496172b48488b38676caca3778 --- /dev/null +++ b/lib/component/bisago_drawer.dart @@ -0,0 +1,93 @@ +import 'package:flutter/material.dart'; +import 'package:ppl_disabilitas/config/styles.dart'; + +class BisaGoDrawer extends StatelessWidget { + final List> drawerList = [ + {'title': 'Beranda', 'icon': Icons.home}, + {'title': 'Riwayat Pencarian', 'icon': Icons.history}, + {'title': 'Tentang Aplikasi', 'icon': Icons.info}, + {'title': 'Log out', 'icon': Icons.keyboard_backspace} + ]; + + @override + Widget build(BuildContext context) { + List menus = drawerList.map((menu) { + return _createListTile( + context: context, icon: menu['icon'], title: menu['title']); + }).toList(); + List drawerItem = [ + Container( + height: 130, + child: DrawerHeader( + decoration: BoxDecoration( + color: greenPrimary, + ), + child: Row( + children: [ + FloatingActionButton( + backgroundColor: Colors.white, + elevation: 0, + onPressed: () => {}, + ), + Padding( + padding: EdgeInsets.all(doubleSpace), + child: Text( + 'Nama Orang', + style: TextStyle( + fontSize: 20, + color: Colors.white, + fontFamily: 'Muli', + ), + ), + ), + ], + ), + ), + ), + Container( + decoration: + BoxDecoration(border: Border(top: BorderSide(color: Colors.white))), + ), + ]; + menus.forEach((menu) { + drawerItem.add(menu); + }); + return Theme( + data: Theme.of(context).copyWith( + canvasColor: greenPrimary, + ), + child: Drawer( + child: ListView(padding: EdgeInsets.zero, children: drawerItem), + ), + ); + } + + Widget _createListTile({BuildContext context, IconData icon, String title}) { + return Container( + child: ListTile( + leading: Icon( + icon, + color: Colors.white, + size: 30, + ), + title: Text( + title, + style: TextStyle( + fontSize: 20, + color: Colors.white, + fontFamily: 'Muli', + ), + ), + onTap: () { + Navigator.pop(context); + }, + ), + decoration: BoxDecoration( + color: greenPrimary, + border: Border( + bottom: BorderSide(color: Colors.white), + ), + ), + ); + } +} diff --git a/lib/config/strings.dart b/lib/config/strings.dart new file mode 100644 index 0000000000000000000000000000000000000000..0162847de9bfef0804b5b982a287419cc9838126 --- /dev/null +++ b/lib/config/strings.dart @@ -0,0 +1,16 @@ +// Frequently used strings are stored here +// No hardcoding string view files. Store here. + +final String devBaseURL = "poipole.herokuapp.com"; +final String baseURL = "poipole.herokuapp.com"; +String key = ""; +String csrf = ""; +String sessionId = ""; + +setKey(String newKey) { + key = newKey; +} + +setSessionId(String newSessionId) { + sessionId = newSessionId; +} \ No newline at end of file diff --git a/lib/config/styles.dart b/lib/config/styles.dart new file mode 100644 index 0000000000000000000000000000000000000000..3b140b67428cd2b3e08642963582324ae7d0420e --- /dev/null +++ b/lib/config/styles.dart @@ -0,0 +1,21 @@ +import 'package:flutter/material.dart'; + +final Color greenPrimary = Color(0xff3A903A); +final Color redPrimary = Color(0xffC60000); +final Color bluePrimary = Color(0xff537AC6); + +final double smallSpace = 4.0; +final double regularSpace = 8.0; +final double doubleSpace = 16.0; +final double tripleSpace = 32.0; +final double quartetSpace = 64.0; +final double spaceFourtyEight = 48.0; + +final List regularShadow = [ + BoxShadow( + blurRadius: 4, + color: Colors.black.withOpacity(0.25), + offset: Offset(0, 0)) +]; +final BorderRadius regularBorderRadius = BorderRadius.circular(10); +final BorderRadius doubleBorderRadius = BorderRadius.circular(20); diff --git a/lib/flavor/flavor.dart b/lib/flavor/flavor.dart new file mode 100644 index 0000000000000000000000000000000000000000..09201b9c32fa3cd40c726742a9164dc3768f497f --- /dev/null +++ b/lib/flavor/flavor.dart @@ -0,0 +1,16 @@ +import 'package:ppl_disabilitas/config/strings.dart'; + +enum BuildFlavor { production, development } + +class ApiFlavor { + static String flavor; + + static String getBaseUrl() { + if (ApiFlavor.flavor == BuildFlavor.development.toString()) { + return devBaseURL; + } else { + return baseURL; + } + } + +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..aaab915666b9af6288858f0d23c2cfa1106286f8 --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,9 @@ +import 'package:flutter/material.dart'; +import 'package:ppl_disabilitas/app.dart'; + +import 'flavor/flavor.dart'; + +void main() { + ApiFlavor.flavor = BuildFlavor.production.toString(); + runApp(BisaGo()); +} \ No newline at end of file diff --git a/lib/main_dev.dart b/lib/main_dev.dart new file mode 100644 index 0000000000000000000000000000000000000000..606b2d7f8e1a6d839fcae9ac697d7aad7f7fa337 --- /dev/null +++ b/lib/main_dev.dart @@ -0,0 +1,8 @@ +import 'package:flutter/material.dart'; +import 'package:ppl_disabilitas/app.dart'; +import 'flavor/flavor.dart'; + +void main() { + ApiFlavor.flavor = BuildFlavor.development.toString(); + runApp(BisaGo()); +} \ No newline at end of file diff --git a/lib/model/lokasi.dart b/lib/model/lokasi.dart new file mode 100644 index 0000000000000000000000000000000000000000..7981aec880c098aa96785a6515d9084cb99127b6 --- /dev/null +++ b/lib/model/lokasi.dart @@ -0,0 +1,25 @@ +import 'package:json_annotation/json_annotation.dart'; +part 'lokasi.g.dart'; +@JsonSerializable() +class LokasiListResponse { + List listLokasi; + + LokasiListResponse(); + factory LokasiListResponse.fromJson(List json) => _$LokasiListResponseFromJson(json); + Map toJson() => _$LokasiListResponseToJson(this); +} + +@JsonSerializable(nullable: true) +class Lokasi { + String nama; + double latitude; + double longitude; + String alamat; + String foto; + String telp; + + Lokasi(); + + factory Lokasi.fromJson(Map json) => _$LokasiFromJson(json); + Map toJson() => _$LokasiToJson(this); +} diff --git a/lib/model/lokasi.g.dart b/lib/model/lokasi.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..a5ec83050b8de86fb48eeeb2c8dd560f82f1567d --- /dev/null +++ b/lib/model/lokasi.g.dart @@ -0,0 +1,40 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'lokasi.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +LokasiListResponse _$LokasiListResponseFromJson(List json) { + return LokasiListResponse() + ..listLokasi = json + ?.map((e) => + e == null ? null : Lokasi.fromJson(e as Map)) + ?.toList(); +} + +Map _$LokasiListResponseToJson(LokasiListResponse instance) => + { + 'listLokasi': instance.listLokasi, + }; + + +Lokasi _$LokasiFromJson(Map json) { + return Lokasi() + ..nama = json['nama'] as String + ..latitude = (json['latitude'] as num)?.toDouble() + ..longitude = (json['longitude'] as num)?.toDouble() + ..alamat = json['alamat'] as String + ..foto = json['foto'] as String + ..telp = json['telp'] as String; +} + +Map _$LokasiToJson(Lokasi instance) => { + 'nama': instance.nama, + 'latitude': instance.latitude, + 'longitude': instance.longitude, + 'alamat': instance.alamat, + 'foto': instance.foto, + 'telp': instance.telp, +}; diff --git a/lib/network/CustomException.dart b/lib/network/CustomException.dart new file mode 100644 index 0000000000000000000000000000000000000000..7d533760addfda8e9f174f86d4caef0ac0f8c9b6 --- /dev/null +++ b/lib/network/CustomException.dart @@ -0,0 +1,27 @@ +class CustomException implements Exception { + final _message; + final _prefix; + + CustomException([this._message, this._prefix]); + + String toString() { + return "$_prefix$_message"; + } +} + +class FetchDataException extends CustomException { + FetchDataException([String message]) + : super(message, "Error During Communication: "); +} + +class BadRequestException extends CustomException { + BadRequestException([message]) : super(message, "Invalid Request: "); +} + +class UnauthorisedException extends CustomException { + UnauthorisedException([message]) : super(message, "Unauthorised: "); +} + +class InvalidInputException extends CustomException { + InvalidInputException([String message]) : super(message, "Invalid Input: "); +} \ No newline at end of file diff --git a/lib/network/cookies_interface.dart b/lib/network/cookies_interface.dart new file mode 100644 index 0000000000000000000000000000000000000000..6a6a079ff8212cee11a02f13dc6be5080228ac8f --- /dev/null +++ b/lib/network/cookies_interface.dart @@ -0,0 +1,98 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:path_provider/path_provider.dart'; +import 'package:ppl_disabilitas/config/strings.dart'; + +class CookiesInterface { + Future checkCookieFileAvailability({String fileName}) async { + Directory dir; + await getApplicationDocumentsDirectory().then((Directory directory) { + dir = directory; + }); + File cookieFile = File("${dir.path}/$fileName.json"); + bool cookiesExist = cookieFile.existsSync(); + + return cookiesExist; + } + + Future createSignInCookie({ + Map responseHeaders}) async { + try { + String setCookie; + String csrfToken; + String sessionId; + String userKey; + List cookiesList; + Directory dir; + + await getApplicationDocumentsDirectory().then((Directory directory) { + dir = directory; + }); + File cookieFile = File("${dir.path}/usercookies.json"); + cookieFile.createSync(); + + setCookie = responseHeaders["set-cookie"]; + if (setCookie != null) { + csrfToken = setCookie.split(";")[0].split("=")[1]; + sessionId = setCookie.split(";")[4].split(",")[1].split("=")[1]; + userKey = key; + } + cookiesList = [ + csrfToken, + sessionId, + userKey, + ]; + cookieFile.writeAsStringSync(json.encode(cookiesList)); + return cookieFile; + } on Exception catch (e) { + print(e.toString()); + rethrow; + } + } + + Future createSearchHistoryCookie({ + Map recentSearch}) async { + print("recent searrch $recentSearch"); + Directory dir; + List currentSearchHistory; + try { + await getApplicationDocumentsDirectory().then((Directory directory) { + dir = directory; + }); + File cookieFile = File(dir.path + "/searchhistory.json"); + cookieFile.createSync(); + await checkCookieFileAvailability(fileName: "searchhistory").then((available) async { + if (available) { + await getCookieFile(fileName: "searchhistory").then((cookie) { + bool test = cookie == null; + print("cookie is null? $test"); + if (cookie == null) { + currentSearchHistory = []; + } else { + currentSearchHistory = json.decode(cookie); + } + currentSearchHistory.add(recentSearch); + }); + } else { + currentSearchHistory = []; + } + await cookieFile.writeAsString(json.encode(currentSearchHistory)); + }); + return cookieFile; + } on Exception catch (e) { + print(e.toString()); + rethrow; + } + } + + Future getCookieFile({String fileName}) async { + Directory dir; + await getApplicationDocumentsDirectory().then((Directory directory) { + dir = directory; + }); + File file = File("${dir.path}/$fileName.json"); + dynamic res = file.readAsStringSync(); + return res; + } +} diff --git a/lib/network/data/network_model.dart b/lib/network/data/network_model.dart new file mode 100644 index 0000000000000000000000000000000000000000..f42bffafabfe8b772622147ab6b0e697dddfc463 --- /dev/null +++ b/lib/network/data/network_model.dart @@ -0,0 +1,16 @@ +class NetworkModel { + Status status; + T data; + String message; + + NetworkModel.loading(this.message) : status = Status.LOADING; + NetworkModel.completed(this.data) : status = Status.COMPLETED; + NetworkModel.error(this.message) : status = Status.ERROR; + + @override + String toString() { + return "Status : $status \n Message : $message \n Data : $data"; + } +} + +enum Status { LOADING, COMPLETED, ERROR } diff --git a/lib/network/network_interface.dart b/lib/network/network_interface.dart new file mode 100644 index 0000000000000000000000000000000000000000..a451cf3934eafb869984372427c71a5aad9b6e95 --- /dev/null +++ b/lib/network/network_interface.dart @@ -0,0 +1,94 @@ +import 'dart:convert'; +import 'package:ppl_disabilitas/network/CustomException.dart'; +import 'package:http/http.dart' as http; +import 'dart:io'; + +class NetworkInterface { + //String key = KEY; + + // POST request + Future post({ + String url, //url nya apa + dynamic bodyParams, //data apa yang mau dikasih + bool isLogin, //dia login apa ngga + }) async { + var responseJson; + Map headersJson = + await _buildRequestHeader(isLogin); //butuh header apa ngga + try { + final response = await http.post( + "$url", + body: json.encode(bodyParams), + headers: headersJson, + ); + responseJson = _response(response); + } on SocketException { + throw FetchDataException("No Internet Connection"); + } + return responseJson; + } + + // GET request + Future get({ + String url, + bool isLogin, + }) async { + var responseJson; + Map headersJson = await _buildRequestHeader(isLogin); + try { + final response = await http.get( + "$url", + headers: headersJson, + ); + responseJson = _response(response); + } on SocketException { + throw FetchDataException("No Internet Connection"); + } + return responseJson; + } + + // buildRequestHeader: untuk nentuin pake header apa aja berdasarkan login apa ngga + Future> _buildRequestHeader(bool isLogin) async { + Map headers = Map(); + headers.putIfAbsent("Content-Type", () => "application/json"); + //if (isLogin) { + //List cookieFile = await CookiesInterface().getCookieFile( + // fileName: + // "userCookies"); //ngambil data dari yg udh disimpen di cookie + //print("cookieFile list --> ${cookieFile.toString()}"); + //print("check key here >>> $key"); + //setKey(cookieFile[2]); + //key = cookieFile[2]; + //headers.putIfAbsent( + // "Authorization", + // () => + // 'Token $key'); //ini kalau authorization nya ngga ada baru taro token nya + //headers.putIfAbsent("X-CSRFToken", () => cookieFile[0]); //csrf token + //headers.putIfAbsent( + // "Cookie", + // () => + // "csrftoken=${cookieFile[0]};sessionid=${cookieFile[1]}"); //cookie file + //print("headers --> ${headers}"); + //} + return headers; + } + + dynamic _response(http.Response response) { + switch (response.statusCode) { + case 200: + var responseJson = json.decode(response.body.toString()); + return responseJson; + case 400: + throw BadRequestException(response.body.toString()); + case 401: + + case 403: + throw UnauthorisedException(response.body.toString()); + case 500: + + default: + throw FetchDataException( + 'Error occured while Communication with Server with status : ${response.statusCode}'); + } + } +} diff --git a/lib/page/dashboard/dashboard.dart b/lib/page/dashboard/dashboard.dart new file mode 100644 index 0000000000000000000000000000000000000000..a8c24ec04d86ccf7a26ad49651e23816c808e6e3 --- /dev/null +++ b/lib/page/dashboard/dashboard.dart @@ -0,0 +1,180 @@ +import 'dart:async'; +import 'package:location/location.dart'; +import 'package:flutter/material.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:ppl_disabilitas/component/bisago_appbar.dart'; +import 'package:ppl_disabilitas/component/bisago_drawer.dart'; +import 'package:ppl_disabilitas/config/styles.dart'; +import 'package:ppl_disabilitas/page/pencarian/pencarian.dart'; + +class Dashboard extends StatefulWidget { + DashboardState createState() => DashboardState(); +} + +class DashboardState extends State { + final Completer _controller = Completer(); + final double cameraZoom = 16; + final LatLng defaultLocation = LatLng(-6.1753924, 106.8249641); + final String currentLocationIconAsset = "assets/icon/current_loc.png"; + Location location; + Set _markers = Set(); + LocationData currentLocation; + BitmapDescriptor currentLocationIcon; + bool _serviceEnabled; + PermissionStatus _permissionGranted; + Marker contohMarker = Marker( + markerId: MarkerId("contoh1"), + position: LatLng(-6.365474, 106.828157), + infoWindow: InfoWindow(title: "Fasilkom"), + icon: BitmapDescriptor.defaultMarkerWithHue( + BitmapDescriptor.hueViolet, + ), + ); + + @override + void initState() { + super.initState(); + location = Location(); + enableLocationService(); + location.onLocationChanged().listen((LocationData cLoc) { + currentLocation = cLoc; + updatePinOnMap(); + }); + setSourceAndDestinationIcons(); + setInitialLocation(); + _markers.add(contohMarker); + } + + void enableLocationService() async { + await location.changeSettings(accuracy: LocationAccuracy.HIGH); + _serviceEnabled = await location.serviceEnabled(); + if (!_serviceEnabled) { + _serviceEnabled = await location.requestService(); + if (!_serviceEnabled) { + return; + } + } + _permissionGranted = await location.hasPermission(); + if (_permissionGranted == PermissionStatus.DENIED) { + _permissionGranted = await location.requestPermission(); + if (_permissionGranted != PermissionStatus.GRANTED) { + return; + } + } + } + + void _navigateToPencarianPage(BuildContext context) { + final route = MaterialPageRoute(builder: (_) => Pencarian()); + Navigator.of(context).push(route); + } + + static const textFieldKey = Key('Text Field Mau Kemana'); + @override + Widget build(BuildContext context) { + return Scaffold( + drawer: BisaGoDrawer(), + body: Stack(key: Key("Stack"),children: [ + _buildGoogleMap(context), + InkWell( + key: Key("Navigate to Pencarian"), + onTap: () => _navigateToPencarianPage(context), + child: Container( + key: Key("Container Text Field"), + margin: EdgeInsets.only( + left: doubleSpace, right: doubleSpace, top: doubleSpace), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: doubleBorderRadius, + boxShadow: regularShadow), + child: TextFormField( + enabled: false, + key: Key("Text Field Mau Kemana"), + decoration: InputDecoration( + prefixIcon: Icon( + Icons.search, + color: greenPrimary, + size: 25, + ), + border: InputBorder.none, + fillColor: Colors.white, + labelText: 'Kamu mau kemana?', + labelStyle: TextStyle( + color: greenPrimary, + fontSize: 20, + fontFamily: 'Muli', + fontWeight: FontWeight.w700), + suffixIcon: IconButton( + key: Key("IconButton Text Field"), + icon: Icon( + Icons.mic, + color: greenPrimary, + size: 25, + ), + onPressed: () {})), + onTap: () => _navigateToPencarianPage(context), + ), + ), + ), + ]), + appBar: PreferredSize( + preferredSize: Size.fromHeight(55), + child: BisaGoAppBar(), + key: Key("Scaffold Text Field"), + ), + ); + } + + Widget _buildGoogleMap(BuildContext context) { + CameraPosition initialCameraPosition = CameraPosition( + target: defaultLocation, + zoom: cameraZoom, + ); + if (currentLocation != null) { + initialCameraPosition = CameraPosition( + target: LatLng(currentLocation.latitude, currentLocation.longitude), + zoom: cameraZoom, + ); + } + return Container( + key: Key("Container GoogleMap"), + height: MediaQuery.of(context).size.height, + width: MediaQuery.of(context).size.width, + child: GoogleMap( + key: Key("Google Map"), + markers: _markers, + mapType: MapType.normal, + initialCameraPosition: initialCameraPosition, + onMapCreated: (GoogleMapController controller) { + _controller.complete(controller); + }, + ), + ); + } + + void setSourceAndDestinationIcons() async { + currentLocationIcon = await BitmapDescriptor.fromAssetImage( + ImageConfiguration(devicePixelRatio: 5), currentLocationIconAsset); + } + + void updatePinOnMap() async { + CameraPosition cPosition = CameraPosition( + zoom: cameraZoom, + target: LatLng(currentLocation.latitude, currentLocation.longitude), + ); + final GoogleMapController controller = await _controller.future; + await controller.animateCamera(CameraUpdate.newCameraPosition(cPosition)); + setState(() { + var pinPosition = + LatLng(currentLocation.latitude, currentLocation.longitude); + _markers.removeWhere((m) => m.markerId.value == 'currentLocationPin'); + _markers.add(Marker( + markerId: MarkerId('currentLocationPin'), + position: pinPosition, + icon: currentLocationIcon)); + }); + } + + void setInitialLocation() async { + currentLocation = await location.getLocation(); + } +} diff --git a/lib/page/pencarian/pencarian.dart b/lib/page/pencarian/pencarian.dart new file mode 100644 index 0000000000000000000000000000000000000000..20aad672ac0a2174716f9d4aedeeb68b47196732 --- /dev/null +++ b/lib/page/pencarian/pencarian.dart @@ -0,0 +1,216 @@ +import 'package:flutter/material.dart'; +import 'package:ppl_disabilitas/bloc/LokasiResponseBloc.dart'; +import 'package:ppl_disabilitas/config/styles.dart'; +import 'package:ppl_disabilitas/model/lokasi.dart'; +import 'package:ppl_disabilitas/network/data/network_model.dart'; + +class Pencarian extends StatefulWidget { + @override + PencarianState createState() => PencarianState(); +} + +class PencarianState extends State { + Icon searchIcon = Icon(Icons.search); + Widget appBarText = Text("Pencarian Lokasi"); + LokasiResponseBloc _bloc = LokasiResponseBloc(); + LokasiListResponse lokasiFromApi; + LokasiListResponse recentSearch; + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: greenPrimary, + leading: IconButton( + icon: Icon(Icons.arrow_back_ios, size: 25), + key: Key("Back Icon Key"), + onPressed: () => Navigator.pop(context, 'Take me back')), + title: Container( + margin: EdgeInsets.only(top: doubleSpace, bottom: doubleSpace), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: doubleBorderRadius, + boxShadow: regularShadow), + child: TextFormField( + key: Key("Text Field Mau Kemana"), + decoration: InputDecoration( + contentPadding: EdgeInsets.all(0), + isDense: false, + prefixIcon: Icon( + Icons.search, + color: greenPrimary, + size: 25, + ), + border: InputBorder.none, + fillColor: Colors.white, + labelText: 'Kamu mau kemana?', + labelStyle: TextStyle( + color: greenPrimary, + fontSize: 18, + fontFamily: 'Muli', + fontWeight: FontWeight.w700), + suffixIcon: IconButton( + icon: Icon( + Icons.mic, + color: greenPrimary, + size: 25, + ), + onPressed: () {})), + ), + ), + ), + body: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + StreamBuilder>( + stream: _bloc.recentSearchStream, + builder: (context, snapshot) { + if (snapshot.hasData) { + switch (snapshot.data.status) { + case Status.LOADING: + return Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(greenPrimary), + ), + ); + break; + case Status.COMPLETED: + recentSearch = snapshot.data.data; + Widget displayWidget; + if (recentSearch.listLokasi.isEmpty) { + displayWidget = Center( + child: Text("Anda belum pernah melakukan pencarian")); + } else { + displayWidget = makeLokasiWidget("history",recentSearch); + } + return Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + margin: EdgeInsets.all(doubleSpace), + child: Text( + "Pencarian terdahulu", + style: TextStyle( + fontFamily: 'Muli', fontSize: 15), + )), + Flexible(child: displayWidget), + ], + )); + break; + case Status.ERROR: + return Center( + child: Text("${snapshot.data.status}"), + ); + break; + } + } + return Container(); + }, + ), + Container( + margin: EdgeInsets.only(left: doubleSpace, top: regularSpace, bottom: smallSpace), + child: Text("Hasil Pencarian"), + ), + StreamBuilder>( + stream: _bloc.lokasiListStream, + builder: (context, snapshot) { + if (snapshot.hasData) { + switch (snapshot.data.status) { + case Status.LOADING: + return Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(greenPrimary), + ), + ); + break; + case Status.COMPLETED: + lokasiFromApi = snapshot.data.data; + return Expanded( + flex: 2, child: makeLokasiWidget("api",lokasiFromApi)); + break; + case Status.ERROR: + return Center( + child: Text(snapshot.data.data.toString()), + ); + break; + } + } + return Container(); + }, + ), + ], + ), + ); + } + + Widget makeLokasiWidget(String key, LokasiListResponse places) { + return ListView.builder( + shrinkWrap: true, + itemCount: places.listLokasi.length, + itemBuilder: (context, index) { + return InkWell( + key: Key("$key-${places.listLokasi[index].nama}"), + onTap: () { + _bloc.saveRecentSearch(places.listLokasi[index]); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.transparent, + border: Border(bottom: BorderSide(color: Colors.grey[400]))), + margin: EdgeInsets.only(left: doubleSpace, right: doubleSpace), + height: 90, + child: Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + CircleAvatar( + backgroundColor: greenPrimary, + child: Text('Test'), + ), + Container( + padding: EdgeInsets.all(doubleSpace), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + places.listLokasi[index].nama, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w800, + color: Colors.black, + fontFamily: 'Muli', + ), + ), + Text( + places.listLokasi[index].alamat, + style: TextStyle( + fontSize: 15, + color: Colors.black, + fontFamily: 'Muli', + ), + ), + ], + ), + ), + ], + ), + Icon( + Icons.arrow_forward_ios, + color: Colors.grey[400], + size: 20, + ) + ], + ), + ), + ); + }); + } +} diff --git a/lib/repository/LokasiRepository.dart b/lib/repository/LokasiRepository.dart new file mode 100644 index 0000000000000000000000000000000000000000..c838e73314e65d3f4f834419af97339fcc154f48 --- /dev/null +++ b/lib/repository/LokasiRepository.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; + +import 'package:ppl_disabilitas/model/lokasi.dart'; +import 'package:ppl_disabilitas/network/cookies_interface.dart'; +import 'package:ppl_disabilitas/network/network_interface.dart'; + +class LokasiRepository { + NetworkInterface _network = NetworkInterface(); + + Future fetchLokasi() async { + final response = await _network.get( + url: 'https://my.api.mockaroo.com/mall.json?key=dbcde960', + isLogin: false); + return LokasiListResponse.fromJson(response); + } + + Future fetchRecentSearch() async { + var response; + await CookiesInterface().checkCookieFileAvailability(fileName: "searchhistory").then((boolean) async { + if (!boolean) { + response = []; + } else { + await CookiesInterface().getCookieFile(fileName: "searchhistory").then((cookie) { + response = json.decode(cookie); + print("response type: ${response.runtimeType}"); + }); + } + }); + return LokasiListResponse.fromJson(response); + } + + Future saveRecentSearch(Lokasi recentSearch) async { + Map searchToMap = recentSearch.toJson(); + await CookiesInterface() + .createSearchHistoryCookie(recentSearch: searchToMap); + } +} diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1cb5a249b676e90484c1283954d5728d5ee6a4c2 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,127 @@ +name: ppl_disabilitas +description: Project PPL layanan aplikasi disabilitas + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.1.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + http: ^0.12.0+2 + mockito: ^4.1.1 + intl: + location: ^2.5.3 + flutter_plugin_android_lifecycle: ^1.0.6 + flutter_polyline_points: ^0.1.0 + path_provider: ^1.6.5 + cupertino_icons: ^0.1.2 + google_maps_flutter: ^0.5.24+1 + flutter_dotenv: ^2.1.0 + json_serializable: ^3.2.5 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_launcher_icons: ^0.7.4 + # Linter dependency + pedantic: ^1.8.0 # The default Linter package used in Google + build_runner: ^1.8.0 + +flutter_icons: + android: "launcher_icon" + ios: true + image_path: "assets/icon/icon_launcher.png" + + #mockito: ^4.1.1 +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/icon/loc.png + - assets/icon/current_loc.png + - assets/icon/icon_launcher.png + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + fonts: + - family: Muli + fonts: + - asset: assets/fonts/Muli-Regular.ttf + style: normal + - asset: assets/fonts/Muli-SemiBold.ttf + weight: 700 + - asset: assets/fonts/Muli-SemiBoldItalic.ttf + weight: 700 + style: italic + - asset: assets/fonts/Muli-Black.ttf + weight: 900 + - asset: assets/fonts/Muli-BlackItalic.ttf + weight: 900 + style: italic + - asset: assets/fonts/Muli-Bold.ttf + weight: 800 + - asset: assets/fonts/Muli-BoldItalic.ttf + weight: 800 + style: italic + - asset: assets/fonts/Muli-ExtraLight.ttf + weight: 100 + - asset: assets/fonts/Muli-ExtraLightItalic.ttf + weight: 100 + style: italic + - asset: assets/fonts/Muli-Italic.ttf + style: italic + - asset: assets/fonts/Muli-Light.ttf + weight: 200 + - asset: assets/fonts/Muli-LightItalic.ttf + weight: 200 + style: italic + - asset: assets/fonts/Muli-Medium.ttf + weight: 600 + - asset: assets/fonts/Muli-MediumItalic.ttf + weight: 600 + style: italic + - family: Comfortaa + fonts: + - asset: assets/fonts/Comfortaa-Regular.ttf + style: normal + - asset: assets/fonts/Comfortaa-Light.ttf + weight: 200 + - asset: assets/fonts/Comfortaa-Medium.ttf + weight: 600 + - asset: assets/fonts/Comfortaa-SemiBold.ttf + weight: 700 + - asset: assets/fonts/Comfortaa-Bold.ttf + weight: 800 + + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000000000000000000000000000000000000..5847c14108dce8e30f81d40e458b18f3b894f376 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,16 @@ +# SonarScanner properties file +## Server +sonar.host.url=https://pmpl.cs.ui.ac.id/sonarqube + +## Path to sources +sonar.sources=lib +#sonar.exclusions= +#sonar.inclusions= +## Path to tests +sonar.tests=test +sonar.coverage.exclusions = lib/model/*, lib/config/*, lib/flavor/*, lib/main_dev.dart, lib/main.dart +#sonar.test.exclusions= +#sonar.test.inclusions= +## Source encoding +sonar.sourceEncoding=UTF-8 +## Branch analysis diff --git a/test/cookie_test.dart b/test/cookie_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..7a35a8c56f354eaaf63900337eba435e49f43118 --- /dev/null +++ b/test/cookie_test.dart @@ -0,0 +1,63 @@ +import 'dart:io'; +import 'package:flutter/services.dart'; +import 'package:mockito/mockito.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:ppl_disabilitas/network/cookies_interface.dart'; + +class MockCookiesInterface extends Mock implements CookiesInterface {} + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + MethodChannel channel = + const MethodChannel('plugins.flutter.io/path_provider'); + setUpAll(() async { + // Create a temporary directory. + final directory = await Directory.systemTemp.createTemp(); + + // Mock out the MethodChannel for the path_provider plugin. + channel.setMockMethodCallHandler((MethodCall methodCall) async { + // If you're getting the apps documents directory, return the path to the + // temp directory on the test environment instead. + if (methodCall.method == 'getApplicationDocumentsDirectory') { + return directory.path; + } + return null; + }); + }); + CookiesInterface mockHttpClient; + test('Creates cookie file for sign in session', () async { + final responseHeaderFromSignIn = { + "set-cookie": + "csrftoken=v4E6UNpTMUMAoDxMoSZUBVPuAh7mkIb96DfRcakdivghb0d57yvCZxbbya7L3kFv; expires=Fri, 05 Mar 2021 03:33:39 GMT; Max-Age=31449600; Path=/; SameSite=Lax;sessionid=vrarp9pga02bwr97duemf6ym94gjgepn; expires=Fri, 20 Mar 2020 03:33:39 GMT; HttpOnly; Max-Age=1209600; Path=/; SameSite=Lax", + }; + mockHttpClient = MockCookiesInterface(); + String rootDir = + await channel.invokeMethod('getApplicationDocumentsDirectory'); + when(mockHttpClient.createSignInCookie( + responseHeaders: responseHeaderFromSignIn)) + .thenAnswer((_) async { + await Future.delayed(Duration(milliseconds: 50)); + return Future.value(File("$rootDir/usercookies.json")); + }); + // combine with sign in test here + }); + test('Creates cookie file after search', () async { + final recentSearch = { + "nama": "Johnson", + "latitude": -2.9062039, + "longitude": 114.6905436, + "alamat": "2460 Comanche Crossing", + "telepon": "+62 805 612 4225" + }; + String rootDir = + await channel.invokeMethod("getApplicationDocumentsDirectory"); + when(mockHttpClient.createSearchHistoryCookie( + recentSearch: recentSearch + )) + .thenAnswer((_) async { + await Future.delayed(Duration(milliseconds: 50)); + return Future.value(File("$rootDir/usercookies.json")); + }); + // combine with sign in test here + }); +} diff --git a/test/mock_test.dart b/test/mock_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..537257fa5a6978b2f3df1af8853a28e8a10733c0 --- /dev/null +++ b/test/mock_test.dart @@ -0,0 +1,87 @@ +import 'package:flutter/material.dart'; +import 'package:mockito/mockito.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:ppl_disabilitas/network/network_interface.dart'; +import 'package:ppl_disabilitas/page/dashboard/dashboard.dart'; +import 'package:http/http.dart' as http; +import 'package:pedantic/pedantic.dart'; + +class MockNavigatorObserver extends Mock implements NavigatorObserver {} + +class MockNetwork extends Mock implements NetworkInterface {} + +class MockHttp extends Mock implements http.Client {} + +void main() { + group('Dashboard navigation tests', () { + NavigatorObserver mockObserver; + NetworkInterface mockNetwork; + MockHttp mockHttp; + setUp(() { + mockObserver = MockNavigatorObserver(); + mockNetwork = MockNetwork(); + mockHttp = MockHttp(); + when(mockHttp.get('http://wwww.google.com')) + .thenAnswer((_) async => http.Response('{"title": "Test"}', 200)); + when(mockNetwork.get(isLogin: false, url: anyNamed('url'))) + .thenAnswer((_) async { + await Future.delayed(Duration(milliseconds: 50)); + return Future.value([ + { + "nama": "Coolidge", + "latitude": -23.7169139, + "longitude": -46.8498038, + "alamat": "74809 Hooker Drive", + "telepon": "+55 956 836 5799" + } + ]); + }); + }); + + Future _buildDashboardPage(WidgetTester tester) async { + await tester.pumpWidget(MaterialApp( + home: Dashboard(), + + /// This mocked observer will now receive all navigation events + /// that happen in our app. + navigatorObservers: [mockObserver], + )); + + /// The tester.pumpWidget() call above just built our app widget + /// and triggered the pushObserver method on the mockObserver once. + verify(mockObserver.didPush(any, any)); + } + + Future _navigateToPencarianPage(WidgetTester tester) async { + final textFieldKey = Key("Text Field Mau Kemana"); + await tester.tap(find.byKey(textFieldKey)); + await tester.pump(); + } + + testWidgets( + 'when tapping text form field, should navigate to pencarian page', + (WidgetTester tester) async { + final textFieldKeyPencarian = Key("Text Field Mau Kemana"); + await _buildDashboardPage(tester); + await _navigateToPencarianPage(tester); + + verify(mockObserver.didPush(any, any)); + expect(find.byKey(textFieldKeyPencarian), findsOneWidget); + }); + + testWidgets('tapping the back button should navigate back to the dashboard', + (WidgetTester tester) async { + final backIconKey = Key("Back Icon Key"); + await _buildDashboardPage(tester); + await _navigateToPencarianPage(tester); + await tester.pump(); + final Route pushedRoute = + verify(mockObserver.didPush(captureAny, any)).captured.single; + String popResult; + unawaited(pushedRoute.popped.then((result) => popResult = result)); + await tester.tap(find.byKey(backIconKey)); + await tester.pumpAndSettle(); + expect(popResult, 'Take me back'); + }); + }); +} diff --git a/test/pencarian_test.dart b/test/pencarian_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d97d6fa52dab8fc659aba95621c683faba17b95a --- /dev/null +++ b/test/pencarian_test.dart @@ -0,0 +1,58 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:ppl_disabilitas/page/pencarian/pencarian.dart'; +import 'package:ppl_disabilitas/network/network_interface.dart'; + +class MockNetwork extends Mock implements NetworkInterface {} + +void main() { + MockNetwork mockNetwork; + setUp(() { + mockNetwork = MockNetwork(); + when(mockNetwork.get(isLogin: false, url: anyNamed('url'))).thenAnswer((_) async { + await Future.delayed(Duration(milliseconds: 50)); + return Future.value( + [ + { + "nama": "Coolidge", + "latitude": -23.7169139, + "longitude": -46.8498038, + "alamat": "74809 Hooker Drive", + "telepon": "+55 956 836 5799" + } + ] + ); + }); + }); + testWidgets('display list view in pencarian', (WidgetTester tester) async { + // Provide the childWidget to the Container. + await tester.pumpWidget(MaterialApp(home: Pencarian())); + await tester.enterText(find.byKey(const Key("Text Field Mau Kemana")), "Coolidge"); + await tester.pump(); + + expect(find.byKey(const Key("api-Coolidge")), findsOneWidget); + // [TODO] tiap item itu punya key unik + // Search for the childWidget in the tree and verify it exists. + //expect(find.byType(ListView), findsNWidgets); + //expect(find.byType(Container), findsWidgets); + //expect(find.byType(Icon), findsWidgets); + }); + + testWidgets('finds a text field in pencarian', (WidgetTester tester) async { + final textFieldKey = Key("Text Field Mau Kemana"); + await tester.pumpWidget(MaterialApp(home: Pencarian())); + expect(find.byKey(textFieldKey), findsOneWidget); + }); + +} diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..0a223972d3cab637dbed4c8c3d3ed006175fa98c --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:google_maps_flutter/google_maps_flutter.dart'; +import 'package:ppl_disabilitas/app.dart'; +import 'package:ppl_disabilitas/page/dashboard/dashboard.dart'; + +void main() { + testWidgets('finds a text field in dashboard', (WidgetTester tester) async { + final containerTextField = Key("Container Text Field"); + final iconButtonTextField = Key("IconButton Text Field"); + final textFieldKey = Key("Text Field Mau Kemana"); + final scaffoldTextFieldKey = Key("Scaffold Text Field"); + // Provide the childWidget to the Container. + await tester.pumpWidget(MaterialApp(home: Dashboard())); + // Search for the childWidget in the tree and verify it exists. + expect(find.byType(Scaffold), findsOneWidget); + expect(find.byKey(Key("Stack")), findsOneWidget); + expect(find.byType(TextFormField), findsOneWidget); + expect(find.byType(Icon), findsNWidgets(3)); + expect(find.text('Kamu mau kemana?'), findsOneWidget); + expect(find.text('Kamu mau kmn?'), findsNothing); + expect(find.byKey(containerTextField), findsOneWidget); + expect(find.byKey(iconButtonTextField), findsOneWidget); + expect(find.byKey(textFieldKey), findsOneWidget); + expect(find.byKey(scaffoldTextFieldKey), findsOneWidget); + }); + + testWidgets('finds a google map in dashboard', (WidgetTester tester) async { + final containerGoogleMap = Key("Container GoogleMap"); + final googleMapKey = Key("Google Map"); + await tester.pumpWidget(MaterialApp(home: Dashboard())); + expect(find.byType(GoogleMap), findsOneWidget); + expect(find.byType(Container), findsNWidgets(3)); + expect(find.byKey(googleMapKey), findsOneWidget); + expect(find.byKey(containerGoogleMap), findsOneWidget); + }); + + // testWidgets('finds a marker in google map', (WidgetTester tester) async { + // await tester.pumpWidget(MaterialApp(home: Dashboard())); + // expect(find.byType(Marker), findsOneWidget); + // }); + + testWidgets('finds a navigation bar', (WidgetTester tester) async { + await tester.pumpWidget(MaterialApp(home: Dashboard())); + expect(find.byType(Scaffold), findsOneWidget); + expect(find.byType(Theme), findsOneWidget); + expect(find.byType(AppBar), findsOneWidget); + }); + + testWidgets('Shows dashboard on App Start', (WidgetTester tester) async { + await tester.pumpWidget(BisaGo()); + expect(find.byType(Dashboard), findsOneWidget); + }); +}