commit dbf070041b6ea0c4f0734d3a78ffd02fbb408390 Author: developer1054 Date: Tue May 4 16:12:48 2021 -0300 carga inicial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9d532b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json diff --git a/.metadata b/.metadata new file mode 100644 index 0000000..cd984dd --- /dev/null +++ b/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 9b2d32b605630f28625709ebd9d78ab3016b2bf6 + channel: stable + +project_type: app diff --git a/README.md b/README.md new file mode 100644 index 0000000..6ecd506 --- /dev/null +++ b/README.md @@ -0,0 +1,16 @@ +# appcardsstarter + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/android/.gitignore b/android/.gitignore new file mode 100644 index 0000000..0a741cb --- /dev/null +++ b/android/.gitignore @@ -0,0 +1,11 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/android/app/build.gradle b/android/app/build.gradle new file mode 100644 index 0000000..1615dde --- /dev/null +++ b/android/app/build.gradle @@ -0,0 +1,113 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} + +android { + compileSdkVersion 30 + + 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.hightechx.mobile.appcardsstarter" + minSdkVersion 17 + targetSdkVersion 30 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + multiDexEnabled true + } + + signingConfigs { + release { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile file(keystoreProperties['storeFile']) + storePassword keystoreProperties['storePassword'] + } + debug { + keyAlias keystoreProperties['keyAlias'] + keyPassword keystoreProperties['keyPassword'] + storeFile file(keystoreProperties['storeFile']) + storePassword keystoreProperties['storePassword'] + } + } + + 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 + signingConfig signingConfigs.release + minifyEnabled true + useProguard false + + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + splits { + + //Configures multiple APKs based on ABI. + abi { + + //Enables building multiple APKs per ABI. + enable true + + //By default all ABIs are included, so use reset() and include to specify that we only + //want APKs for x86 and x86_64. + + //Resets the list of ABIs that Gradle should create APKs for to none. + reset() + + //Specifies a list of ABIs that Gradle should create APKs for. + include "x86", "x86_64", "armeabi", "armeabi-v7a", "arm64-v8a" + + //Specifies that we do not want to also generate a universal APK that includes all ABIs. + universalApk false + } + } +} + +flutter { + source '../..' +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'com.google.firebase:firebase-messaging:21.0.1' +} +apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..befa58b --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,114 @@ +{ + "project_info": { + "project_number": "661329313113", + "project_id": "iconnectstarter", + "storage_bucket": "iconnectstarter.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:661329313113:android:ee416225872cd1b375a048", + "android_client_info": { + "package_name": "com.hightechx.mobile.appcardsstarter" + } + }, + "oauth_client": [ + { + "client_id": "661329313113-080glr5andokt54tv4hrsq2aa1gc60dl.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hightechx.mobile.appcardsstarter", + "certificate_hash": "64cead3173785642d31904f0f7d5036aba3a82e1" + } + }, + { + "client_id": "661329313113-8drmvbmivptkfk74umh33e70iqn23v4h.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hightechx.mobile.appcardsstarter", + "certificate_hash": "ce5f6fbc5eae2dc39f5e4a36ff2f85ea2c269676" + } + }, + { + "client_id": "661329313113-blgbjmo9853q56n6ilgr1e8a8hhh3k2j.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCwdjw-NID4KGmJpb9QsDPZAcHVU6DUxpw" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "661329313113-blgbjmo9853q56n6ilgr1e8a8hhh3k2j.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "661329313113-3hcmlgoji7hpqkmceptvor56m2us1blc.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.hightechx.mobile.iconnectstarter" + } + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:661329313113:android:ff30051390d15f2375a048", + "android_client_info": { + "package_name": "com.hightechx.mobile.iconnectstarter" + } + }, + "oauth_client": [ + { + "client_id": "661329313113-4ht8rv9kgodq2l6hou3iuv70ggblo4dh.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hightechx.mobile.iconnectstarter", + "certificate_hash": "ce5f6fbc5eae2dc39f5e4a36ff2f85ea2c269676" + } + }, + { + "client_id": "661329313113-goqg84aulv5tcm5k7n66fdt2gijsnu5k.apps.googleusercontent.com", + "client_type": 1, + "android_info": { + "package_name": "com.hightechx.mobile.iconnectstarter", + "certificate_hash": "64cead3173785642d31904f0f7d5036aba3a82e1" + } + }, + { + "client_id": "661329313113-blgbjmo9853q56n6ilgr1e8a8hhh3k2j.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCwdjw-NID4KGmJpb9QsDPZAcHVU6DUxpw" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "661329313113-blgbjmo9853q56n6ilgr1e8a8hhh3k2j.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "661329313113-3hcmlgoji7hpqkmceptvor56m2us1blc.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.hightechx.mobile.iconnectstarter" + } + } + ] + } + } + } + ], + "configuration_version": "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 0000000..82cf4a1 --- /dev/null +++ b/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..e22200d --- /dev/null +++ b/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/main/kotlin/com/hightechx/mobile/appcardsstarter/MainActivity.kt b/android/app/src/main/kotlin/com/hightechx/mobile/appcardsstarter/MainActivity.kt new file mode 100644 index 0000000..9147b9e --- /dev/null +++ b/android/app/src/main/kotlin/com/hightechx/mobile/appcardsstarter/MainActivity.kt @@ -0,0 +1,6 @@ +package com.hightechx.mobile.appcardsstarter + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} 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 0000000..304732f --- /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 0000000..db77bb4 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-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..17987b7 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-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..09d4391 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-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..d5f1c8d 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-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..4d6372e 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/values/styles.xml b/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..1f83a33 --- /dev/null +++ b/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..82cf4a1 --- /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 0000000..e45998c --- /dev/null +++ b/android/build.gradle @@ -0,0 +1,32 @@ +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.6.3' + classpath 'com.google.gms:google-services:4.3.2' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/android/gradle.properties b/android/gradle.properties new file mode 100644 index 0000000..a673820 --- /dev/null +++ b/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true +android.enableR8=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..90f271d --- /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-6.5-all.zip diff --git a/android/settings.gradle b/android/settings.gradle new file mode 100644 index 0000000..44e62bc --- /dev/null +++ b/android/settings.gradle @@ -0,0 +1,11 @@ +include ':app' + +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() + +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } + +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/assets/images/check.png b/assets/images/check.png new file mode 100644 index 0000000..1411d68 Binary files /dev/null and b/assets/images/check.png differ diff --git a/assets/images/foguete.png b/assets/images/foguete.png new file mode 100644 index 0000000..6b4c300 Binary files /dev/null and b/assets/images/foguete.png differ diff --git a/assets/images/load.gif b/assets/images/load.gif new file mode 100644 index 0000000..a718bd8 Binary files /dev/null and b/assets/images/load.gif differ diff --git a/assets/images/logo.png b/assets/images/logo.png new file mode 100644 index 0000000..a395366 Binary files /dev/null and b/assets/images/logo.png differ diff --git a/ios/.gitignore b/ios/.gitignore new file mode 100644 index 0000000..e96ef60 --- /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 0000000..6b4c0f7 --- /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 0000000..e8efba1 --- /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 0000000..399e934 --- /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 0000000..1e8c3c9 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,41 @@ +# 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 flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..f790248 --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,173 @@ +PODS: + - device_info (0.0.1): + - Flutter + - Firebase/Core (6.33.0): + - Firebase/CoreOnly + - FirebaseAnalytics (= 6.8.3) + - Firebase/CoreOnly (6.33.0): + - FirebaseCore (= 6.10.3) + - Firebase/Messaging (6.33.0): + - Firebase/CoreOnly + - FirebaseMessaging (~> 4.7.0) + - firebase_messaging (0.0.1): + - Firebase/Core + - Firebase/Messaging + - Flutter + - FirebaseAnalytics (6.8.3): + - FirebaseCore (~> 6.10) + - FirebaseInstallations (~> 1.6) + - GoogleAppMeasurement (= 6.8.3) + - GoogleUtilities/AppDelegateSwizzler (~> 6.7) + - GoogleUtilities/MethodSwizzler (~> 6.7) + - GoogleUtilities/Network (~> 6.7) + - "GoogleUtilities/NSData+zlib (~> 6.7)" + - nanopb (~> 1.30906.0) + - FirebaseCore (6.10.3): + - FirebaseCoreDiagnostics (~> 1.6) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/Logger (~> 6.7) + - FirebaseCoreDiagnostics (1.7.0): + - GoogleDataTransport (~> 7.4) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/Logger (~> 6.7) + - nanopb (~> 1.30906.0) + - FirebaseInstallations (1.7.0): + - FirebaseCore (~> 6.10) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/UserDefaults (~> 6.7) + - PromisesObjC (~> 1.2) + - FirebaseInstanceID (4.8.0): + - FirebaseCore (~> 6.10) + - FirebaseInstallations (~> 1.6) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/UserDefaults (~> 6.7) + - FirebaseMessaging (4.7.1): + - FirebaseCore (~> 6.10) + - FirebaseInstanceID (~> 4.7) + - GoogleUtilities/AppDelegateSwizzler (~> 6.7) + - GoogleUtilities/Environment (~> 6.7) + - GoogleUtilities/Reachability (~> 6.7) + - GoogleUtilities/UserDefaults (~> 6.7) + - Protobuf (>= 3.9.2, ~> 3.9) + - Flutter (1.0.0) + - flutter_inappwebview (0.0.1): + - Flutter + - GoogleAppMeasurement (6.8.3): + - GoogleUtilities/AppDelegateSwizzler (~> 6.7) + - GoogleUtilities/MethodSwizzler (~> 6.7) + - GoogleUtilities/Network (~> 6.7) + - "GoogleUtilities/NSData+zlib (~> 6.7)" + - nanopb (~> 1.30906.0) + - GoogleDataTransport (7.5.1): + - nanopb (~> 1.30906.0) + - GoogleUtilities/AppDelegateSwizzler (6.7.2): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (6.7.2): + - PromisesObjC (~> 1.2) + - GoogleUtilities/Logger (6.7.2): + - GoogleUtilities/Environment + - GoogleUtilities/MethodSwizzler (6.7.2): + - GoogleUtilities/Logger + - GoogleUtilities/Network (6.7.2): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (6.7.2)" + - GoogleUtilities/Reachability (6.7.2): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (6.7.2): + - GoogleUtilities/Logger + - nanopb (1.30906.0): + - nanopb/decode (= 1.30906.0) + - nanopb/encode (= 1.30906.0) + - nanopb/decode (1.30906.0) + - nanopb/encode (1.30906.0) + - PromisesObjC (1.2.11) + - Protobuf (3.14.0) + - shared_preferences (0.0.1): + - Flutter + - url_launcher (0.0.1): + - Flutter + - video_player (0.0.1): + - Flutter + - wakelock (0.0.1): + - Flutter + - webview_flutter (0.0.1): + - Flutter + +DEPENDENCIES: + - device_info (from `.symlinks/plugins/device_info/ios`) + - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) + - Flutter (from `Flutter`) + - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) + - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) + - url_launcher (from `.symlinks/plugins/url_launcher/ios`) + - video_player (from `.symlinks/plugins/video_player/ios`) + - wakelock (from `.symlinks/plugins/wakelock/ios`) + - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) + +SPEC REPOS: + trunk: + - Firebase + - FirebaseAnalytics + - FirebaseCore + - FirebaseCoreDiagnostics + - FirebaseInstallations + - FirebaseInstanceID + - FirebaseMessaging + - GoogleAppMeasurement + - GoogleDataTransport + - GoogleUtilities + - nanopb + - PromisesObjC + - Protobuf + +EXTERNAL SOURCES: + device_info: + :path: ".symlinks/plugins/device_info/ios" + firebase_messaging: + :path: ".symlinks/plugins/firebase_messaging/ios" + Flutter: + :path: Flutter + flutter_inappwebview: + :path: ".symlinks/plugins/flutter_inappwebview/ios" + shared_preferences: + :path: ".symlinks/plugins/shared_preferences/ios" + url_launcher: + :path: ".symlinks/plugins/url_launcher/ios" + video_player: + :path: ".symlinks/plugins/video_player/ios" + wakelock: + :path: ".symlinks/plugins/wakelock/ios" + webview_flutter: + :path: ".symlinks/plugins/webview_flutter/ios" + +SPEC CHECKSUMS: + device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 + Firebase: 8db6f2d1b2c5e2984efba4949a145875a8f65fe5 + firebase_messaging: 21344b3b3a7d9d325d63a70e3750c0c798fe1e03 + FirebaseAnalytics: 5dd088bd2e67bb9d13dbf792d1164ceaf3052193 + FirebaseCore: d889d9e12535b7f36ac8bfbf1713a0836a3012cd + FirebaseCoreDiagnostics: 770ac5958e1372ce67959ae4b4f31d8e127c3ac1 + FirebaseInstallations: 466c7b4d1f58fe16707693091da253726a731ed2 + FirebaseInstanceID: bd3ffc24367f901a43c063b36c640b345a4a5dd1 + FirebaseMessaging: 5eca4ef173de76253352511aafef774caa1cba2a + Flutter: 0e3d915762c693b495b44d77113d4970485de6ec + flutter_inappwebview: 69dfbac46157b336ffbec19ca6dfd4638c7bf189 + GoogleAppMeasurement: 966e88df9d19c15715137bb2ddaf52373f111436 + GoogleDataTransport: f56af7caa4ed338dc8e138a5d7c5973e66440833 + GoogleUtilities: 7f2f5a07f888cdb145101d6042bc4422f57e70b3 + nanopb: 59317e09cf1f1a0af72f12af412d54edf52603fc + PromisesObjC: 8c196f5a328c2cba3e74624585467a557dcb482f + Protobuf: 0cde852566359049847168e51bd1c690e0f70056 + shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d + url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef + video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e + wakelock: bfc7955c418d0db797614075aabbc58a39ab5107 + webview_flutter: d2b4d6c66968ad042ad94cbb791f5b72b4678a96 + +PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c + +COCOAPODS: 1.10.0 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..591ceda --- /dev/null +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,563 @@ +// !$*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 */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + A5D82AE8E0E5ED1F5A082514 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 03EF6E7ED0A4FA340455B15B /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 03EF6E7ED0A4FA340455B15B /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 08922355C5E2336BF16B0757 /* 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 = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 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 = ""; }; + 7A5C2200DA6A79155504BE0C /* 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 = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 88355A66513470E8616746C7 /* 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 = ""; }; + 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 = ""; }; + 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A5D82AE8E0E5ED1F5A082514 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 5D86A1CD3012FEC8702550C4 /* Pods */ = { + isa = PBXGroup; + children = ( + 7A5C2200DA6A79155504BE0C /* Pods-Runner.debug.xcconfig */, + 88355A66513470E8616746C7 /* Pods-Runner.release.xcconfig */, + 08922355C5E2336BF16B0757 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 5D86A1CD3012FEC8702550C4 /* Pods */, + C2FF14DC12A785B88E6C1415 /* 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 */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; + C2FF14DC12A785B88E6C1415 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 03EF6E7ED0A4FA340455B15B /* 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 = ( + B306051ED70955E7F20A792F /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + D1269E9237FC7CA90F7F2991 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* 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 */ + 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\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + B306051ED70955E7F20A792F /* [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; + }; + D1269E9237FC7CA90F7F2991 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* 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; + 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 = 9.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.hightechx.mobile.appcardsstarter; + 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; + 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 = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + 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 = 9.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.hightechx.mobile.appcardsstarter; + 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.hightechx.mobile.appcardsstarter; + 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 0000000..1d526a1 --- /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 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..a28140c --- /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 0000000..21a3cc1 --- /dev/null +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /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 0000000..d36b1fa --- /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 0000000..dc9ada4 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 0000000..28c6bf0 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 0000000..2ccbfd9 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 0000000..f091b6b 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 0000000..4cde121 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 0000000..d0ef06e 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 0000000..dcdc230 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 0000000..2ccbfd9 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 0000000..c8f9ed8 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 0000000..a6d6b86 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-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..a6d6b86 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 0000000..75b2d16 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-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..c4df70d 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 0000000..6a84f41 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 0000000..d0e1f58 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 0000000..0bedcf2 --- /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 0000000..9da19ea 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 0000000..9da19ea 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 0000000..9da19ea 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 0000000..89c2725 --- /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 0000000..f2e259c --- /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 0000000..f3c2851 --- /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 0000000..52b22bd --- /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 + appcardsstarter + 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 0000000..308a2a5 --- /dev/null +++ b/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/lib/atualizarapp/atualizarapp.dart b/lib/atualizarapp/atualizarapp.dart new file mode 100644 index 0000000..5fd813b --- /dev/null +++ b/lib/atualizarapp/atualizarapp.dart @@ -0,0 +1,72 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AtualizarScreen extends StatefulWidget { + final String linkLoja; + AtualizarScreen({this.linkLoja}); + @override + _AtualizarScreenState createState() => _AtualizarScreenState(); +} + +class _AtualizarScreenState extends State { + + @override + Widget build(BuildContext context) { + return Scaffold( + // appBar: AppBar( + // title: Text('Aplicativos'), + // ), + body: Container( + padding: const EdgeInsets.all(8.0), + width: double.maxFinite, + color: Colors.white70, + child: Stack( + //fit: StackFit.loose, + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Container( + height: MediaQuery.of(context).size.height * 0.4, + child: Image.asset('assets/images/foguete.png',fit: BoxFit.contain,), + ), + SizedBox(height: 25.0,), + Text('Atualização necessária',style: TextStyle(fontSize: 18.0,fontWeight: FontWeight.bold,color: Colors.grey.shade800),), + SizedBox(height: 25.0,), + Text('A versão atual deste aplicativo não é mais suportada. Por favor atualize o app.',textAlign: TextAlign.center,style: TextStyle(fontWeight: FontWeight.w300,color: Colors.grey.shade800)), + Expanded( + child: SafeArea( + bottom: true, + minimum: const EdgeInsets.only(bottom: 30.0), + child: Flex( + direction: Axis.vertical, + mainAxisAlignment: MainAxisAlignment.end, + children: [ + MaterialButton( + color: Theme.of(context).primaryColor, + minWidth: MediaQuery.of(context).size.width * 0.6, + child: Text('ATUALIZAR AGORA'), + textColor: Colors.white, + //minWidth: MediaQuery.of(context).size.width * 0.5, + elevation: 0, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.0) + ), + onPressed: (){ + launch(widget.linkLoja); + } + ), + ], + ), + ), + ) + ], + ), + ], + ) + ), + ); + } +} \ No newline at end of file diff --git a/lib/default_response_api.dart b/lib/default_response_api.dart new file mode 100644 index 0000000..a04d36b --- /dev/null +++ b/lib/default_response_api.dart @@ -0,0 +1,97 @@ +class DefaultResponseApi { + int errorCode; + String errorMessage; + + DefaultResponseApi({this.errorCode, this.errorMessage}); + + DefaultResponseApi.fromJson(Map json) { + errorCode = json['ErrorCode']; + errorMessage = json['ErrorMessage']; + } + + Map toJson() { + final Map data = new Map(); + data['ErrorCode'] = this.errorCode; + data['ErrorMessage'] = this.errorMessage; + return data; + } +} + +class RegistraDeviceRequest { + int aPPMOBILECODIGO; + int pLATAFORMAMOBILECODIGO; + String dEVICETOKEN; + String mODELODEVICE; + int uSUCOD; + + RegistraDeviceRequest( + {this.aPPMOBILECODIGO, + this.pLATAFORMAMOBILECODIGO, + this.dEVICETOKEN, + this.mODELODEVICE, + this.uSUCOD}); + + RegistraDeviceRequest.fromJson(Map json) { + aPPMOBILECODIGO = json['APP_MOBILE_CODIGO']; + pLATAFORMAMOBILECODIGO = json['PLATAFORMA_MOBILE_CODIGO']; + dEVICETOKEN = json['DEVICE_TOKEN']; + mODELODEVICE = json['MODELO_DEVICE']; + uSUCOD = json['USU_COD']; + } + + Map toJson() { + final Map data = new Map(); + data['APP_MOBILE_CODIGO'] = this.aPPMOBILECODIGO; + data['PLATAFORMA_MOBILE_CODIGO'] = this.pLATAFORMAMOBILECODIGO; + data['DEVICE_TOKEN'] = this.dEVICETOKEN; + data['MODELO_DEVICE'] = this.mODELODEVICE; + data['USU_COD'] = this.uSUCOD; + return data; + } +} + +class ApiStatusResponse { + String sistema; + String upload; + String download; + String pagamento; + int errorCode; + String errorMessage; + + ApiStatusResponse( + {this.sistema, + this.upload, + this.download, + this.pagamento, + this.errorCode, + this.errorMessage}); + + ApiStatusResponse.fromJson(Map json) { + sistema = json['Sistema']; + upload = json['Upload']; + download = json['Download']; + pagamento = json['Pagamento']; + errorCode = json['ErrorCode']; + errorMessage = json['ErrorMessage']; + } +} + +class VersaoMinimaResponse { + int versaoMinima; + String linkLoja; + String nome; + int errorCode; + String errorMessage; + bool vOk; + + VersaoMinimaResponse({this.errorCode, this.errorMessage,this.linkLoja,this.nome,this.versaoMinima,this.vOk}); + + VersaoMinimaResponse.fromJson(Map json) { + errorCode = json['ErrorCode']; + errorMessage = json['ErrorMessage']; + versaoMinima = json['VersaoMinima']; + linkLoja = json['LinkLoja']; + nome = json['Nome']; + vOk = true; + } +} \ No newline at end of file diff --git a/lib/funcoes_gerais.dart b/lib/funcoes_gerais.dart new file mode 100644 index 0000000..be661ce --- /dev/null +++ b/lib/funcoes_gerais.dart @@ -0,0 +1,147 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'package:device_info/device_info.dart'; +import 'dart:io'; + +import 'default_response_api.dart'; + +class FuncoesGerais{ + + //static const String urlLexLiteApi = "https://apis.lexstation.com/api/v1/"; + static const String tokenPadrao = "XW3Y21GZWD9HIB8XOME4UE2APLPG3J"; + static const String urlBaseNewCore = "https://newcore.services/newcore/"; + static const int appMobileCodigo = 18; + static const String nomeApp = "App Cards Starter"; + static const int versaoAtual = 100; + static const String youtubeApiKey = "AIzaSyAmqjP0MxgASbt98Px1_hqaIvcsqeHO15k";//"AIzaSyA8jo3qsr-JJRm40iSHfkrzaMZXdMjo9v4"; + static const String channelId = "UCJ_EUoswNTvRGotJ-ROxaKw"; + static const String homeURL = "https://www.decpisos.com.br/"; + static const String dominioPermitido = "https://www.decpisos.com.br"; + + + static Future checkInternetConnection() async{ + bool retorno = true; + try { + final result = await InternetAddress.lookup('google.com').timeout(Duration(seconds: 5)); + if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) { + retorno = true; + } + else{ + retorno = false; + } + } on SocketException catch (_) { + retorno = false; + } + catch(err){ + retorno = false; + } + + return retorno; + } + + static Future getUsuToken()async{ + return Future.value(tokenPadrao); + } + + static Future registraDevice(String token) async{ + + if(await FuncoesGerais.checkInternetConnection()){ + if(token != null && token.isNotEmpty){ + + String url = FuncoesGerais.urlBaseNewCore+ "api/v1/user/${FuncoesGerais.tokenPadrao}/registra_device"; + Map heads = Map(); + heads["Content-type"] = "application/json; charset=utf-8"; + heads["auth-key"] = token; + DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + String model = ""; + int platformCoddigo = 0; + if (Platform.isAndroid) { + platformCoddigo = 2; + var info = await deviceInfo.androidInfo; + model = info.model; + } else if (Platform.isIOS) { + platformCoddigo = 1; + var info = await deviceInfo.iosInfo; + model = info.utsname.machine; + } + + var objPost = new RegistraDeviceRequest( + aPPMOBILECODIGO: appMobileCodigo, + dEVICETOKEN: token, + mODELODEVICE: model, + pLATAFORMAMOBILECODIGO: platformCoddigo, + uSUCOD: 0, + ); + + try { + var body = json.encode(objPost); + //var response = await http.post(url, body: body,headers: heads); + var r = await http.post(url, body: body,headers: heads); + print(r); + // if (response != null) { + // if (response.statusCode == 200) { + // var data = jsonDecode(response.body); + // retorno = LoginResponse.fromJson(data); + // } + // } + } catch (e) { + } + + } + } + else{ + print('Nada'); + } + } + + static Future checkVersaoMinimaOk() async{ + VersaoMinimaResponse objRetorno = VersaoMinimaResponse( + errorCode: 0, + errorMessage: '', + linkLoja: '', + nome: '', + versaoMinima: 0, + vOk: true + ); + if(await FuncoesGerais.checkInternetConnection()){ + String url = FuncoesGerais.urlBaseNewCore + "api/v1/appmobile/${FuncoesGerais.tokenPadrao}/versaominima/$appMobileCodigo"; + Map heads = Map(); + heads["Content-type"] = "application/json; charset=utf-8"; + + try { + var response = await http.get(url,headers: heads); + if (response != null) { + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + objRetorno = VersaoMinimaResponse.fromJson(data); + // PackageInfo packageInfo = await PackageInfo.fromPlatform(); + // var v = packageInfo.version.split('.'); + // int versaoAtual = 0; + //if(v.length > 0)versaoAtual = v[0] != null && v[0].isNotEmpty ? int.parse(v[0]) : 0; + if(FuncoesGerais.versaoAtual != null && objRetorno.versaoMinima > FuncoesGerais.versaoAtual){ + objRetorno.vOk = false; + } + } + else{ + objRetorno.errorCode = 4; + objRetorno.errorMessage = 'Falha na comunição com a API error:${response.statusCode}.'; + } + } + else{ + objRetorno.errorCode = 3; + objRetorno.errorMessage = 'Falha na comunição com o server.'; + } + } catch (e) { + objRetorno.errorCode = 2; + objRetorno.errorMessage = 'Falha na comunição com o server.'; + } + } + else{ + objRetorno.errorCode = 1; + objRetorno.errorMessage = 'Sem Conexão com a internet.'; + } + + return objRetorno; + } + +} \ No newline at end of file diff --git a/lib/home/home.dart b/lib/home/home.dart new file mode 100644 index 0000000..e28f1e6 --- /dev/null +++ b/lib/home/home.dart @@ -0,0 +1,60 @@ +import 'package:appcardsstarter/funcoes_gerais.dart'; +import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'package:webview_flutter/webview_flutter.dart'; + +class HomeScreen extends StatefulWidget { + @override + _HomeScreenState createState() => _HomeScreenState(); +} + +class _HomeScreenState extends State with AutomaticKeepAliveClientMixin { + bool error = false; + String msg = ''; + @override + Widget build(BuildContext context) { + super.build(context); + return SafeArea( + child: this.error ? this._buildError() : WebView( + initialUrl: FuncoesGerais.homeURL, + javascriptMode: JavascriptMode.unrestricted, + onWebResourceError: (err){ + this.error = true; + this.msg = err.description; + setState(() { + }); + }, + navigationDelegate: (navigation){ + print(navigation.url); + if (navigation.url.startsWith(FuncoesGerais.dominioPermitido)) { + return NavigationDecision.navigate; + } + //print('allowing navigation to $request'); + launch(navigation.url); + return NavigationDecision.prevent; + }, + ), + ); + } + + Widget _buildError(){ + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(msg), + RaisedButton(onPressed: (){ + this.error = false; + this.msg = ''; + setState(() { + }); + }, child: Text('Atualizar'),) + ], + ), + ); + } + + @override + bool get wantKeepAlive => true; +} \ No newline at end of file diff --git a/lib/index/index.dart b/lib/index/index.dart new file mode 100644 index 0000000..5036da4 --- /dev/null +++ b/lib/index/index.dart @@ -0,0 +1,55 @@ +import 'package:appcardsstarter/home/home.dart'; +import 'package:appcardsstarter/notificacoes/notificacoes.dart'; +import 'package:appcardsstarter/videos/youtube_videos.dart'; +import 'package:convex_bottom_bar/convex_bottom_bar.dart'; +import 'package:flutter/material.dart'; + +class IndexScreen extends StatefulWidget { + @override + _IndexScreenState createState() => _IndexScreenState(); +} + +class _IndexScreenState extends State with SingleTickerProviderStateMixin{ + TabController _tabController; + + @override + void initState() { + super.initState(); + _tabController = TabController(length: 3, vsync: this); + _tabController.index = 1; + } + + @override + void dispose() { + _tabController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: TabBarView( + controller: _tabController, + physics: NeverScrollableScrollPhysics(), + children: [ + YouTubeVideosScreen(), + HomeScreen(), + NotificacoesScreen() + ] + ), + bottomNavigationBar: ConvexAppBar( + items: [ + TabItem(icon: Icons.video_collection, title: 'Vídeos'), + TabItem(icon: Icons.home, title: 'Home'), + TabItem(icon: Icons.notifications, title: 'Notificações'), + ], + style: TabStyle.flip, + backgroundColor: Theme.of(context).primaryColor, + controller: _tabController, + // onTap: (int i){ + // print(i); + // }, + ), + ); + } +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart new file mode 100644 index 0000000..0820a1d --- /dev/null +++ b/lib/main.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; +import 'package:get/get.dart'; + +import 'splash/splash.dart'; + +void main() { + runApp(GetMaterialApp( + title: 'LEX Station Lite', + localizationsDelegates: [ + // ... app-specific localization delegate[s] here + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate + ], + supportedLocales: [ + const Locale('pt'), + ], + themeMode: ThemeMode.dark, + theme: ThemeData( + brightness: Brightness.dark, + visualDensity: VisualDensity.adaptivePlatformDensity, + ), + home: SplashScreen() + )); +} + diff --git a/lib/notificacoes/api/notificacoes_api.dart b/lib/notificacoes/api/notificacoes_api.dart new file mode 100644 index 0000000..03498ef --- /dev/null +++ b/lib/notificacoes/api/notificacoes_api.dart @@ -0,0 +1,159 @@ + +import 'dart:convert'; + +import 'package:http/http.dart' as http; + +import '../../default_response_api.dart'; +import '../../funcoes_gerais.dart'; +import 'notificacoes_classes.dart'; + +class NotificacoesApi{ + + Future getNotificacoes(int pagina,{String lidas = 'T',String curtidas = 'T'}) async{ + var retorno = new NotificacoesResponse( + errorCode: 0, + errorMessage: "", + loadMore: false, + results: [] + ); + if(await FuncoesGerais.checkInternetConnection() == false){ + retorno.errorCode = 1; + retorno.errorMessage = "Sem conexão com a Internet"; + } + else{ + var token = await FuncoesGerais.getUsuToken(); + String url = FuncoesGerais.urlBaseNewCore+'api/v1/user/notificacoes/$token/$pagina/10/$lidas/$curtidas'; + Map heads = Map(); + heads["Content-type"] = "application/json; charset=utf-8"; + + var response = await http.get(url, headers: heads); + + if (response != null) { + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + retorno = NotificacoesResponse.fromJson(data); + } + else{ + retorno.errorCode = response.statusCode; + retorno.errorMessage = "Falha: ${response.statusCode}"; + } + } + else{ + retorno.errorCode = 2; + retorno.errorMessage = "Falha na comunicação com o server. Tente novamente"; + } + } + + return retorno; + } + + Future getNotificacao(int id) async{ + var retorno = new NotificacaoResponse( + errorCode: 0, + errorMessage: "" + ); + + if(await FuncoesGerais.checkInternetConnection() == false){ + retorno.errorCode = 1; + retorno.errorMessage = "Sem conexão com a Internet"; + } + else{ + var token = await FuncoesGerais.getUsuToken(); + String url = FuncoesGerais.urlBaseNewCore+'api/v1/user/notificacao/$token/$id'; + Map heads = Map(); + heads["Content-type"] = "application/json; charset=utf-8"; + + var response = await http.get(url, headers: heads); + + if (response != null) { + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + retorno = NotificacaoResponse.fromJson(data); + } + else{ + retorno.errorCode = response.statusCode; + retorno.errorMessage = "Falha: ${response.statusCode}"; + } + } + else{ + retorno.errorCode = 2; + retorno.errorMessage = "Falha na comunicação com o server. Tente novamente"; + } + } + + return retorno; + } + + Future notificacaoLike(NotificacaoLikeRequest post) async{ + DefaultResponseApi objRetorno = new DefaultResponseApi(); + + if(await FuncoesGerais.checkInternetConnection() == false){ + objRetorno.errorCode = 1; + objRetorno.errorMessage = "Sem Conexão com a Internet."; + return objRetorno; + } + + var token = await FuncoesGerais.getUsuToken(); + String url = FuncoesGerais.urlBaseNewCore+'api/v1/user/notificacaolike/$token'; + Map heads = Map(); + heads["Content-type"] = "application/json; charset=utf-8"; + + var body = json.encode(post); + + var response = await http.post(url, headers: heads, body: body); + + if (response != null) { + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + objRetorno = DefaultResponseApi.fromJson(data); + } + else{ + objRetorno.errorCode = response.statusCode; + objRetorno.errorMessage = "Falha: ${response.statusCode}"; + } + } + else{ + objRetorno.errorCode = 2; + objRetorno.errorMessage = "Falha na comunicação com o server. Tente novamente"; + } + + return objRetorno; + } + + Future notificacaoLida(NotificacaoLidaRequest post, int notificacaoId) async{ + DefaultResponseApi objRetorno = new DefaultResponseApi(); + if(await FuncoesGerais.checkInternetConnection() == false){ + objRetorno.errorCode = 1; + objRetorno.errorMessage = "Sem Conexão com a Internet."; + return objRetorno; + } + + var token = await FuncoesGerais.getUsuToken(); + String url = FuncoesGerais.urlBaseNewCore+'api/v1/user/notificacaolida/$token/$notificacaoId'; + Map heads = Map(); + heads["Content-type"] = "application/json; charset=utf-8"; + + var body = json.encode(post); + + var response = await http.post(url, headers: heads, body: body); + + + if (response != null) { + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + objRetorno = DefaultResponseApi.fromJson(data); + } + else{ + objRetorno.errorCode = response.statusCode; + objRetorno.errorMessage = "Falha: ${response.statusCode}"; + } + } + else{ + objRetorno.errorCode = 2; + objRetorno.errorMessage = "Falha na comunicação com o server. Tente novamente"; + } + + return objRetorno; + } + +} \ No newline at end of file diff --git a/lib/notificacoes/api/notificacoes_classes.dart b/lib/notificacoes/api/notificacoes_classes.dart new file mode 100644 index 0000000..a9a4b88 --- /dev/null +++ b/lib/notificacoes/api/notificacoes_classes.dart @@ -0,0 +1,142 @@ +class NotificacaoLikeRequest { + int iD; + String like; + + NotificacaoLikeRequest({this.iD, this.like}); + + NotificacaoLikeRequest.fromJson(Map json) { + iD = json['ID']; + like = json['Like']; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['Like'] = this.like; + return data; + } +} + +class NotificacaoLidaRequest { + String latitude; + String longitude; + + NotificacaoLidaRequest({this.latitude, this.longitude}); + + NotificacaoLidaRequest.fromJson(Map json) { + latitude = json['Latitude']; + longitude = json['Longitude']; + } + + Map toJson() { + final Map data = new Map(); + data['Latitude'] = this.latitude; + data['Longitude'] = this.longitude; + return data; + } +} + + +class NotificacaoResponse { + NotificacaoResults result; + int errorCode; + String errorMessage; + + NotificacaoResponse({this.result, this.errorCode, this.errorMessage}); + + NotificacaoResponse.fromJson(Map json) { + result = + json['Result'] != null ? new NotificacaoResults.fromJson(json['Result']) : null; + errorCode = json['ErrorCode']; + errorMessage = json['ErrorMessage']; + } + + Map toJson() { + final Map data = new Map(); + if (this.result != null) { + data['Result'] = this.result.toJson(); + } + data['ErrorCode'] = this.errorCode; + data['ErrorMessage'] = this.errorMessage; + return data; + } +} + +class NotificacoesResponse { + List results; + int errorCode; + String errorMessage; + bool loadMore; + + NotificacoesResponse({this.results, this.errorCode, this.errorMessage,this.loadMore}); + + NotificacoesResponse.fromJson(Map json) { + if (json['Results'] != null) { + results = new List(); + json['Results'].forEach((v) { + results.add(new NotificacaoResults.fromJson(v)); + }); + } + errorCode = json['ErrorCode']; + errorMessage = json['ErrorMessage']; + } + + Map toJson() { + final Map data = new Map(); + if (this.results != null) { + data['Results'] = this.results.map((v) => v.toJson()).toList(); + } + data['ErrorCode'] = this.errorCode; + data['ErrorMessage'] = this.errorMessage; + return data; + } +} + +class NotificacaoResults { + int iD; + String titulo; + String texto; + String conteudo; + String dataNotificacao; + String tipoConteudo; + bool visualizado; + String imageUrl; + String like; + + NotificacaoResults( + {this.iD, + this.titulo, + this.texto, + this.conteudo, + this.dataNotificacao, + this.tipoConteudo, + this.visualizado, + this.imageUrl, + this.like = ''}); + + NotificacaoResults.fromJson(Map json) { + iD = json['ID']; + titulo = json['Titulo'] ?? ''; + texto = json['Texto']; + conteudo = json['Conteudo']; + dataNotificacao = json['DataNotificacao']; + tipoConteudo = json['TipoConteudo']; + visualizado = json['Visualizado']; + imageUrl = json['ImageUrl']; + like = json['Like'] ?? ''; + } + + Map toJson() { + final Map data = new Map(); + data['ID'] = this.iD; + data['Titulo'] = this.titulo; + data['Texto'] = this.texto; + data['Conteudo'] = this.conteudo; + data['DataNotificacao'] = this.dataNotificacao; + data['TipoConteudo'] = this.tipoConteudo; + data['Visualizado'] = this.visualizado; + data['ImageUrl'] = this.imageUrl; + data['Like'] = this.like; + return data; + } +} \ No newline at end of file diff --git a/lib/notificacoes/notificacao.dart b/lib/notificacoes/notificacao.dart new file mode 100644 index 0000000..7950216 --- /dev/null +++ b/lib/notificacoes/notificacao.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_html/flutter_html.dart'; +import 'package:get/get.dart'; +import 'package:url_launcher/url_launcher.dart'; +import 'notificacoes_controller.dart'; + +class NotificacaoDetail extends StatelessWidget { + final NotificacoesController c = Get.find(); + + @override + Widget build(BuildContext context) { + + return Scaffold( + appBar: AppBar( + // + //title: Obx(() => Text(c.notificacaoDetail.value.result.titulo ?? 'Notificação')), + ), + body: Obx(() => c.loadingDetail.value ? Center(child: CircularProgressIndicator(),) : c.notificacaoDetail.value.errorCode != 0 ? Center(child: Text(c.notificacaoDetail.value.errorMessage),) : ListView( + children: [ + Visibility( + visible: GetUtils.isNullOrBlank(c.notificacaoDetail.value.result.imageUrl) == false, + child: Container( + color: Colors.black38, + height: 250, + child: Padding( + padding: const EdgeInsets.all(70.0), + child: Image.network( + c.notificacaoDetail.value.result.imageUrl ?? '', + fit: BoxFit.contain, + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + c.notificacaoDetail.value.result.titulo, + style: TextStyle(fontSize: 30.0,), + ), + const SizedBox(height: 10), + Html( + data: c.notificacaoDetail.value.result.conteudo, + onLinkTap: (url){ + launch(url); + }, + // style: Theme.of(context).textTheme.bodyText2.copyWith( + // color: Colors.black54, + // height: 1.5, + // fontSize: 16.0, + // ), + ), + ], + ), + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/notificacoes/notificacoes.dart b/lib/notificacoes/notificacoes.dart new file mode 100644 index 0000000..088ca09 --- /dev/null +++ b/lib/notificacoes/notificacoes.dart @@ -0,0 +1,168 @@ +import 'package:flutter/material.dart'; +import 'package:animations/animations.dart'; +import 'package:get/get.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import 'notificacao.dart'; +import 'notificacoes_controller.dart'; +//import 'package:supercharged/supercharged.dart'; + +class NotificacoesScreen extends StatelessWidget { + final NotificacoesController c = Get.put(NotificacoesController()); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Notificações'), + centerTitle: false, + ), + body: Obx(() => c.loading.value ? Center(child: CircularProgressIndicator(),) : c.errorCode.value != 0 ? this._buildError() : RefreshIndicator( + onRefresh: c.refresh, + // child: AnimatedList( + // key: c.listKey, + // padding: const EdgeInsets.all(8.0), + // initialItemCount: c.notificacoesResults.length + 1, + // itemBuilder: (context,index,animation){ + // if (index < c.notificacoesResults.length) { + // return SlideTransition( + // //position: c.animation, + // position: Tween( + // begin: const Offset(-1, 0), + // end: Offset(0, 0), + // ).animate(animation), + // child: this._buildListTile(index) + // ); + // } else if (index > 1) { + // if(c.loadMore == null || c.loadMore){ + // c.getNotificacoesBloc(); + // return Container( + // height: 40, + // width: 40, + // alignment: Alignment.center, + // child: CircularProgressIndicator(), + // ); + // } + // else{ + // return Center(child: Padding( + // padding: const EdgeInsets.only(top: 8.0), + // child: Text("Não há mais Notificações para exibir."), + // ),); + // } + // } + // else { + // return Center(child: Padding( + // padding: const EdgeInsets.only(top: 8.0), + // child: Text("Não há mais Notificações para exibir."), + // ),); + // } + // } + // ), + child: ListView.builder( + padding: const EdgeInsets.all(8.0), + itemCount: c.notificacoesResults.length + 1, + itemBuilder: (_,index){ + if (index < c.notificacoesResults.length) { + return this._buildListTile(index); + // return SlideTransition( + // position: c.animation, + // child: this._buildListTile(index) + // ); + } else if (index > 1) { + if(c.loadMore == null || c.loadMore){ + c.getNotificacoesBloc(); + return Container( + height: 40, + width: 40, + alignment: Alignment.center, + child: CircularProgressIndicator(), + ); + } + else{ + return Center(child: Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text("Não há mais Notificações para exibir."), + ),); + } + } + else { + return Center(child: Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text("Não há mais Notificações para exibir."), + ),); + } + }, + ), + )), + // body: ListView( + // padding: const EdgeInsets.all(8.0), + // children: [ + // ...List.generate(10, (int index) { + // return this._buildListTile(index); + // }), + // ], + // ), + ); + } + + Widget _buildError(){ + return Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(c.errorMessage), + RaisedButton(onPressed: c.refresh, child: Text('Atualizar'),) + ], + ), + ); + } + + Widget _buildListTile(int index) { + if(c.notificacoesResults[index].tipoConteudo == 'L'){ + return this._buildListTileTile(index: index,onTap: (){ + c.notificacaoLidaBloc(c.notificacoesResults[index].iD).then((value) => launch(c.notificacoesResults[index].conteudo)); + }); + } + return OpenContainer( + //openColor: Colors.transparent, + closedColor: Colors.black87.withOpacity(0.2), + transitionType: ContainerTransitionType.fadeThrough, + openBuilder: (BuildContext _, VoidCallback openContainer) { + c.notificacoesResults[index].visualizado = true; + c.getNotificacaoDetail(c.notificacoesResults[index].iD); + //return _DetailsPage(); + return NotificacaoDetail(); + }, + onClosed: (bool isMarkedAsDone) { + c.notificacaoLidaBloc(c.notificacoesResults[index].iD); + if (isMarkedAsDone ?? false) + Get.rawSnackbar(message: 'Marked as done!'); + }, + tappable: false, + closedShape: const RoundedRectangleBorder(), + closedElevation: 0.0, + closedBuilder: (BuildContext _, VoidCallback openContainer) { + return this._buildListTileTile(index: index,onTap: openContainer); + }, + ); + } + + Widget _buildListTileTile({Function onTap,@required int index}){ + return ListTile( + leading: CircleAvatar( + backgroundImage: GetUtils.isNullOrBlank(c.notificacoesResults[index].imageUrl) ? AssetImage( + 'assets/images/logo.png', + ) : NetworkImage(c.notificacoesResults[index].imageUrl), + // child: Image.asset( + // 'assets/images/logo.png', + // width: 40, + // ), + ), + onTap: onTap, + trailing: c.notificacoesResults[index].visualizado ? Text('') : Text('●',style: TextStyle(color: Colors.blue),), + title: Text(c.notificacoesResults[index].titulo), + subtitle: Text(c.getDateFormatada(c.notificacoesResults[index].dataNotificacao)), + ); + } +} \ No newline at end of file diff --git a/lib/notificacoes/notificacoes_controller.dart b/lib/notificacoes/notificacoes_controller.dart new file mode 100644 index 0000000..a5a1fa0 --- /dev/null +++ b/lib/notificacoes/notificacoes_controller.dart @@ -0,0 +1,102 @@ +//import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart' show DateFormat; +import 'api/notificacoes_api.dart'; +import 'api/notificacoes_classes.dart'; + +class NotificacoesController extends GetxController with SingleGetTickerProviderMixin{ + var notificacoesResults = List().obs; + bool loadMore = true; + NotificacoesApi _api = new NotificacoesApi(); + var notificacaoDetail = NotificacaoResponse().obs; + int page = 1; + var errorCode = 0.obs; + var errorMessage = ''; + var loading = true.obs; + var loadingDetail = true.obs; + var like = ''.obs; + + final f = DateFormat('dd/MM/yyyy HH:mm:ss'); + + //final GlobalKey listKey = GlobalKey(); + + // AnimationController _controller; + // Animation animation; + + @override + void onInit() { + super.onInit(); + + // _controller = AnimationController( + // duration: const Duration(milliseconds: 650), + // vsync: this, + // )..forward(); + // animation = Tween( + // begin: const Offset(-0.5, 0.0), + // end: const Offset(0.0, 0.0), + // ).animate(CurvedAnimation( + // parent: _controller, + // curve: Curves.easeInCubic, + // )); + this.notificacoesResults = new RxList(); + this.getNotificacoesBloc(); + } + + getNotificacoesBloc()async{ + + var response = await this._api.getNotificacoes(page); + this.loadMore = response.results.length < 1 ? false : true; + if(response.errorCode != 0){ + this.errorCode.value = response.errorCode; + this.errorMessage = response.errorMessage; + } + else{ + //if(this.page > 1)this.listKey.currentState.insertItem(2,duration: const Duration(milliseconds: 1500)); + page++; + this.notificacoesResults.addAll(response.results); + } + + if(this.loading.value)this.loading.value = false; + + } + + getNotificacaoDetail(int id) async { + this.loadingDetail.value = true; + this.notificacaoDetail.value.result = new NotificacaoResults(); + var response = await this._api.getNotificacao(id); + this.notificacaoDetail.value = response; + this.like.value = response.result.like; + this.loadingDetail.value = false; + } + + Future refresh() async{ + this.loading.value = true; + this.page = 1; + this.notificacoesResults = new RxList(); + this.getNotificacoesBloc(); + } + + String get getLike => this.like.value; + + Future notificacaoLikeBloc(NotificacaoLikeRequest item) async { + var response = await this._api.notificacaoLike(item); + if(response != null && response.errorCode == 0) + { + this.notificacaoDetail.value.result.like = item.like; + this.like.value = item.like; + } + } + + String getDateFormatada(String dt){ + String r = ''; + try { + r = this.f.format(DateTime.parse(dt)); + } catch (e) { + } + return r; + } + + Future notificacaoLidaBloc(int notificacaoID) async { + return; + } +} \ No newline at end of file diff --git a/lib/splash/splash.dart b/lib/splash/splash.dart new file mode 100644 index 0000000..d74cdee --- /dev/null +++ b/lib/splash/splash.dart @@ -0,0 +1,45 @@ +import 'package:appcardsstarter/funcoes_gerais.dart'; +import 'package:flutter/material.dart'; +import 'package:animated_splash_screen/animated_splash_screen.dart'; +import 'package:get/get.dart'; +import 'package:page_transition/page_transition.dart'; + +import 'splash_controller.dart'; +class SplashScreen extends StatelessWidget { + final SplashController c = Get.put(SplashController()); + @override + Widget build(BuildContext context) { + return AnimatedSplashScreen.withScreenFunction( + splash: Container( + width: double.maxFinite, + height: Get.size.height, + //color: Colors.red, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + ClipRRect( + borderRadius: BorderRadius.circular(8.0), + child: Container(width: 120.0,height: 120.0,child: Image.asset('assets/images/logo.png',fit: BoxFit.contain,)) + ), + SizedBox(height: 10.0,), + Text(FuncoesGerais.nomeApp,style: TextStyle(color: Colors.green.shade600,fontSize: 22.0),), + LinearProgressIndicator() + ], + ), + ), + //splashIconSize: 90.0, + splashIconSize: Get.size.height, + splashTransition: SplashTransition.slideTransition, + pageTransitionType: PageTransitionType.fade, + backgroundColor: Colors.white, + screenFunction: ()async{ + await c.firebaseCloudMessagingListeners(); + await c.verTutorial(); + var screen = await c.verUsuLogado(); + return screen; + }, + //backgroundColor: Colors.blue + ); + } +} \ No newline at end of file diff --git a/lib/splash/splash_controller.dart b/lib/splash/splash_controller.dart new file mode 100644 index 0000000..e8fd069 --- /dev/null +++ b/lib/splash/splash_controller.dart @@ -0,0 +1,89 @@ +import 'dart:io'; + +import 'package:appcardsstarter/atualizarapp/atualizarapp.dart'; +import 'package:appcardsstarter/index/index.dart'; +import 'package:appcardsstarter/notificacoes/notificacoes.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:get/get.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../funcoes_gerais.dart'; + +class SplashController extends GetxController { + + bool _tutorialOk = false; + FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); + + @override + void onInit() { + super.onInit(); + } + + @override + void onClose() { + super.onClose(); + } + + Future verTutorial()async{ + SharedPreferences prefs = await SharedPreferences.getInstance(); + this._tutorialOk = prefs.getBool('tutorial') ?? false; + } + + Future verUsuLogado()async{ + var resp = await FuncoesGerais.checkVersaoMinimaOk(); + if(resp.vOk){ + SharedPreferences prefs = await SharedPreferences.getInstance(); + var token = prefs.getString('token_notif'); + await FuncoesGerais.registraDevice(token); + return IndexScreen(); + } + else{ + return AtualizarScreen(linkLoja: resp.linkLoja); + } + + } + + Future firebaseCloudMessagingListeners() async{ + try { + + if (_firebaseMessaging == null) return; + + if (Platform.isIOS) iOSPermission(); + + _firebaseMessaging.getToken().then((token) async { + print(token); + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setString('token_notif', token); + }); + + _firebaseMessaging.configure( + onLaunch: this._onNotification, + onMessage: this._onNotification, + //onBackgroundMessage: this._onNotification, + onResume: this._onNotification + ); + } on PlatformException catch (e) { + print(e.message); + } + } + + Future _onNotification(Map message) async{ + Get.to(() => NotificacoesScreen()); + //print(message); + //print(message['aps']['alert']['title']); + //Get.rawSnackbar(message: message['aps']['alert']['title']); + } + + void iOSPermission() { + _firebaseMessaging.requestNotificationPermissions( + IosNotificationSettings(sound: true, badge: true, alert: true)); + _firebaseMessaging.onIosSettingsRegistered + .listen((IosNotificationSettings settings) { + print("Settings registered: $settings"); + }); + } + +} + diff --git a/lib/videos/api/youtube_api.dart b/lib/videos/api/youtube_api.dart new file mode 100644 index 0000000..2a6c5a0 --- /dev/null +++ b/lib/videos/api/youtube_api.dart @@ -0,0 +1,63 @@ +import 'dart:convert'; + +import 'package:http/http.dart' as http; + +import '../../funcoes_gerais.dart'; +import 'youtube_classes.dart'; + +class YouTubeApi{ + + Future getChannelVideos({String nextPageToken = ''}) async { + var retorno = new YouTubeSearchResponse( + errorCode: 0, + errorMessage: '', + etag: '', + items: [], + kind: '', + nextPageToken: '', + ); + + if (await FuncoesGerais.checkInternetConnection() == false) { + retorno.errorCode = 1; + retorno.errorMessage = "Sem conexão com a internet"; + return retorno; + } + + String url = "https://www.googleapis.com/youtube/v3/search?key=${FuncoesGerais.youtubeApiKey}&channelId=${FuncoesGerais.channelId}&part=snippet,id&order=date&maxResults=10"; + + if(nextPageToken.isNotEmpty) url += "&pageToken=$nextPageToken"; + + try{ + var response = await http.get(url); + + if (response != null) { + if (response.statusCode == 200) { + var data = jsonDecode(response.body); + retorno = YouTubeSearchResponse.fromJson(data); + } else { + var data = jsonDecode(response.body); + retorno.errorCode = 2; + retorno.errorMessage = "Erro inesperado, tente novamente mais tarde. #${response.statusCode}"; + if(data != null && data['error'] != null){ + if(data['error']['message'] != null && data['error']['message'].toString().isNotEmpty){ + retorno.errorMessage = data['error']['message'].toString(); + } + } + + return retorno; + } + } else { + retorno.errorCode = 2; + retorno.errorMessage = "Erro inesperado, tente novamente mais tarde"; + return retorno; + } + } catch (e) { + retorno.errorCode = 2; + retorno.errorMessage = "Falha interna no App, tente novamenre mais tarde."; + return retorno; + } + + return retorno; + } + +} \ No newline at end of file diff --git a/lib/videos/api/youtube_classes.dart b/lib/videos/api/youtube_classes.dart new file mode 100644 index 0000000..6323557 --- /dev/null +++ b/lib/videos/api/youtube_classes.dart @@ -0,0 +1,182 @@ +class YouTubeSearchResponse { + String kind; + String etag; + String nextPageToken; + String regionCode; + PageInfo pageInfo; + List items; + int errorCode; + String errorMessage; + + YouTubeSearchResponse({this.kind, this.etag, this.nextPageToken, this.regionCode, this.pageInfo, this.items,this.errorCode = 0, this.errorMessage = ''}); + + YouTubeSearchResponse.fromJson(Map json) { + kind = json['kind'] ?? ''; + etag = json['etag'] ?? ''; + nextPageToken = json['nextPageToken'] ?? ''; + regionCode = json['regionCode'] ?? ''; + pageInfo = json['pageInfo'] != null ? new PageInfo.fromJson(json['pageInfo']) : null; + if (json['items'] != null) { + items = new List(); + json['items'].forEach((v) { items.add(new YouTubeItems.fromJson(v)); }); + } + errorCode = 0; + errorMessage = ''; + } +} + +class PageInfo { + int totalResults; + int resultsPerPage; + + PageInfo({this.totalResults, this.resultsPerPage}); + + PageInfo.fromJson(Map json) { + totalResults = json['totalResults']; + resultsPerPage = json['resultsPerPage']; + } + + Map toJson() { + final Map data = new Map(); + data['totalResults'] = this.totalResults; + data['resultsPerPage'] = this.resultsPerPage; + return data; + } +} + +class YouTubeItems { + String kind; + String etag; + Id id; + Snippet snippet; + + YouTubeItems({this.kind, this.etag, this.id, this.snippet}); + + YouTubeItems.fromJson(Map json) { + kind = json['kind']; + etag = json['etag']; + id = json['id'] != null ? new Id.fromJson(json['id']) : null; + snippet = json['snippet'] != null ? new Snippet.fromJson(json['snippet']) : null; + } + + Map toJson() { + final Map data = new Map(); + data['kind'] = this.kind; + data['etag'] = this.etag; + if (this.id != null) { + data['id'] = this.id.toJson(); + } + if (this.snippet != null) { + data['snippet'] = this.snippet.toJson(); + } + return data; + } +} + +class Id { + String kind; + String videoId; + + Id({this.kind, this.videoId}); + + Id.fromJson(Map json) { + kind = json['kind']; + videoId = json['videoId']; + } + + Map toJson() { + final Map data = new Map(); + data['kind'] = this.kind; + data['videoId'] = this.videoId; + return data; + } +} + +class Snippet { + String publishedAt; + String channelId; + String title; + String description; + Thumbnails thumbnails; + String channelTitle; + String liveBroadcastContent; + String publishTime; + + Snippet({this.publishedAt, this.channelId, this.title, this.description, this.thumbnails, this.channelTitle, this.liveBroadcastContent, this.publishTime}); + + Snippet.fromJson(Map json) { + publishedAt = json['publishedAt']; + channelId = json['channelId']; + title = json['title']; + description = json['description']; + thumbnails = json['thumbnails'] != null ? new Thumbnails.fromJson(json['thumbnails']) : null; + channelTitle = json['channelTitle']; + liveBroadcastContent = json['liveBroadcastContent']; + publishTime = json['publishTime']; + } + + Map toJson() { + final Map data = new Map(); + data['publishedAt'] = this.publishedAt; + data['channelId'] = this.channelId; + data['title'] = this.title; + data['description'] = this.description; + if (this.thumbnails != null) { + data['thumbnails'] = this.thumbnails.toJson(); + } + data['channelTitle'] = this.channelTitle; + data['liveBroadcastContent'] = this.liveBroadcastContent; + data['publishTime'] = this.publishTime; + return data; + } +} + +class Thumbnails { + ThumbDefault thumbDefault; + ThumbDefault medium; + ThumbDefault high; + + Thumbnails({this.thumbDefault, this.medium, this.high}); + + Thumbnails.fromJson(Map json) { + thumbDefault = json['default'] != null ? new ThumbDefault.fromJson(json['default']) : null; + medium = json['medium'] != null ? new ThumbDefault.fromJson(json['medium']) : null; + high = json['high'] != null ? new ThumbDefault.fromJson(json['high']) : null; + } + + Map toJson() { + final Map data = new Map(); + if (this.thumbDefault != null) { + data['default'] = this.thumbDefault.toJson(); + } + if (this.medium != null) { + data['medium'] = this.medium.toJson(); + } + if (this.high != null) { + data['high'] = this.high.toJson(); + } + return data; + } +} + +class ThumbDefault { + String url; + int width; + int height; + + ThumbDefault({this.url, this.width, this.height}); + + ThumbDefault.fromJson(Map json) { + url = json['url']; + width = json['width']; + height = json['height']; + } + + Map toJson() { + final Map data = new Map(); + data['url'] = this.url; + data['width'] = this.width; + data['height'] = this.height; + return data; + } +} \ No newline at end of file diff --git a/lib/videos/bloc/youtube_controller.dart b/lib/videos/bloc/youtube_controller.dart new file mode 100644 index 0000000..2a64c17 --- /dev/null +++ b/lib/videos/bloc/youtube_controller.dart @@ -0,0 +1,83 @@ +import 'package:appcardsstarter/videos/api/youtube_api.dart'; +import 'package:appcardsstarter/videos/api/youtube_classes.dart'; +import 'package:get/get.dart'; +import 'package:intl/intl.dart' show DateFormat; + +class YouTubeController extends GetxController { + YouTubeApi _api = new YouTubeApi(); + + var results = new YouTubeSearchResponse( + errorCode: 0, + errorMessage: '', + items: [], + ).obs; + var itens = [].obs; + bool atualizar = false; + var errorCode = 0.obs; + var errorMessage = ''; + var loading = true.obs; + final f = DateFormat('dd/MM/yyyy HH:mm:ss'); + + @override + void onInit() { + super.onInit(); + + // _controller = AnimationController( + // duration: const Duration(milliseconds: 650), + // vsync: this, + // )..forward(); + // animation = Tween( + // begin: const Offset(-0.5, 0.0), + // end: const Offset(0.0, 0.0), + // ).animate(CurvedAnimation( + // parent: _controller, + // curve: Curves.easeInCubic, + // )); + this.atualizar = true; + this.itens = new RxList(); + this.getChannelVideosBloc(); + } + + Future getChannelVideosBloc({String textoBusca = '-'}) async { + //this.loading.value = true; + if (results == null || atualizar || results.value.errorCode != 0) { + results.value = new YouTubeSearchResponse(); + this.itens = new RxList(); + results.value = await this._api.getChannelVideos(); + results.value.items = results.value.items.where((element) => GetUtils.isNullOrBlank(element.id.videoId) == false).toList(); + this.itens.addAll(results.value.items); + this.errorCode.value = results.value.errorCode; + this.errorMessage = results.value.errorMessage; + this.atualizar = false; + } else if (results.value.nextPageToken != null && results.value.nextPageToken.isNotEmpty) { + var more = await this._api.getChannelVideos(nextPageToken: results.value.nextPageToken); + more.items = more.items.where((element) => GetUtils.isNullOrBlank(element.id.videoId) == false).toList(); + this.errorCode.value = more.errorCode; + this.errorMessage = more.errorMessage; + this.itens.addAll(more.items); + results.value.nextPageToken = more.nextPageToken ?? ''; + results.value.items += more.items; + } + this.loading.value = false; + } + + Future refresh() async { + this.loading.value = true; + this.atualizar = true; + results.value = YouTubeSearchResponse( + errorCode: 0, + errorMessage: '', + items: [], + ); + this.getChannelVideosBloc(); + } + + String getDateFormatada(String dt){ + String r = ''; + try { + r = this.f.format(DateTime.parse(dt)); + } catch (e) { + } + return r; + } +} diff --git a/lib/videos/players/YoutubeCustomWidget.dart b/lib/videos/players/YoutubeCustomWidget.dart new file mode 100644 index 0000000..a0d9f14 --- /dev/null +++ b/lib/videos/players/YoutubeCustomWidget.dart @@ -0,0 +1,273 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter_youtube_view/flutter_youtube_view.dart'; + +// class YoutubeCustomWidget extends StatefulWidget { +// @override +// _MyAppState createState() => _MyAppState(); +// } + +// class _MyAppState extends State +// implements YouTubePlayerListener { +// double _volume = 50; +// double _videoDuration = 0.0; +// double _currentVideoSecond = 0.0; +// String _playerState = ""; +// FlutterYoutubeViewController _controller; +// YoutubeScaleMode _mode = YoutubeScaleMode.none; +// PlaybackRate _playbackRate = PlaybackRate.RATE_1; +// bool _isMuted = false; + +// @override +// void onCurrentSecond(double second) { +// // print("onCurrentSecond second = $second"); +// _currentVideoSecond = second; +// } + +// @override +// void onError(String error) { +// print("onError error = $error"); +// } + +// @override +// void onReady() { +// print("onReady"); +// } + +// @override +// void onStateChange(String state) { +// print("onStateChange state = $state"); +// setState(() { +// _playerState = state; +// }); +// } + +// @override +// void onVideoDuration(double duration) { +// print("onVideoDuration duration = $duration"); +// } + +// void _onYoutubeCreated(FlutterYoutubeViewController controller) { +// this._controller = controller; +// } + +// void _loadOrCueVideo() { +// _controller.loadOrCueVideo('gcj2RUWQZ60', _currentVideoSecond); +// } + +// void _play() { +// _controller.play(); +// } + +// void _pause() { +// _controller.pause(); +// } + +// void _seekTo(double time) { +// _controller.seekTo(time); +// } + +// void _setVolume(int volumePercent) { +// _controller.setVolume(volumePercent); +// } + +// void _changeScaleMode(YoutubeScaleMode mode) { +// setState(() { +// _mode = mode; +// _controller.changeScaleMode(mode); +// }); +// } + +// void _changeVolumeMode(bool isMuted) { +// setState(() { +// _isMuted = isMuted; +// if (isMuted) { +// _controller.setMute(); +// } else { +// _controller.setUnMute(); +// } +// }); +// } + +// void _changePlaybackRate(PlaybackRate playbackRate) { +// setState(() { +// _playbackRate = playbackRate; +// _controller.setPlaybackRate(playbackRate); +// }); +// } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: const Text('Custom UI') +// ), +// body: Stack( +// children: [ +// Container( +// child: FlutterYoutubeView( +// scaleMode: _mode, +// onViewCreated: _onYoutubeCreated, +// listener: this, +// params: YoutubeParam( +// videoId: 'gcj2RUWQZ60', +// showUI: false, +// startSeconds: 0.0, +// autoPlay: false, +// ), +// )), +// Column( +// children: [ +// Text( +// 'Current state: $_playerState', +// style: TextStyle(color: Colors.blue), +// ), +// RaisedButton( +// onPressed: _loadOrCueVideo, +// child: Text('Click reload video'), +// ), +// _buildControl(), +// _buildVolume(), +// _buildScaleModeRadioGroup(), +// _buildPlaybackRate() +// ], +// ) +// ], +// )); +// } + +// Widget _buildControl() { +// return new Row( +// mainAxisAlignment: MainAxisAlignment.spaceEvenly, +// children: [ +// RaisedButton( +// onPressed: _play, +// child: Text('Play'), +// ), +// RaisedButton( +// onPressed: _pause, +// child: Text('Pause'), +// ), +// RaisedButton( +// onPressed: () { +// _seekTo(20.0); +// }, +// child: Text('seekTo 20s'), +// ) +// ], +// ); +// } + +// Widget _buildScaleModeRadioGroup() { +// return new Row( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// new Radio( +// value: YoutubeScaleMode.none, +// groupValue: _mode, +// onChanged: _changeScaleMode, +// ), +// new Text( +// 'none', +// style: TextStyle(color: Colors.blue), +// ), +// new Radio( +// value: YoutubeScaleMode.fitWidth, +// groupValue: _mode, +// onChanged: _changeScaleMode, +// ), +// new Text( +// 'fitWidth', +// style: TextStyle(color: Colors.blue), +// ), +// new Radio( +// value: YoutubeScaleMode.fitHeight, +// groupValue: _mode, +// onChanged: _changeScaleMode, +// ), +// new Text( +// 'fitHeight', +// style: TextStyle(color: Colors.blue), +// ), +// ], +// ); +// } + +// Widget _buildVolume() { +// return new Row( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// new Radio( +// value: false, +// groupValue: _isMuted, +// onChanged: _changeVolumeMode, +// ), +// new Text( +// 'unMute', +// style: TextStyle(color: Colors.blue), +// ), +// new Radio( +// value: true, +// groupValue: _isMuted, +// onChanged: _changeVolumeMode, +// ), +// new Text( +// 'Mute', +// style: TextStyle(color: Colors.blue), +// ) +// ], +// ); +// } + +// Widget _buildPlaybackRate() { +// return new Row( +// mainAxisAlignment: MainAxisAlignment.center, +// children: [ +// new Radio( +// value: PlaybackRate.RATE_0_25, +// groupValue: _playbackRate, +// onChanged: _changePlaybackRate, +// ), +// new Text( +// '0_25', +// style: TextStyle(color: Colors.blue), +// ), +// new Radio( +// value: PlaybackRate.RATE_0_5, +// groupValue: _playbackRate, +// onChanged: _changePlaybackRate, +// ), +// new Text( +// '0_5', +// style: TextStyle(color: Colors.blue), +// ), +// new Radio( +// value: PlaybackRate.RATE_1, +// groupValue: _playbackRate, +// onChanged: _changePlaybackRate, +// ), +// new Text( +// '1', +// style: TextStyle(color: Colors.blue), +// ), +// new Radio( +// value: PlaybackRate.RATE_1_5, +// groupValue: _playbackRate, +// onChanged: _changePlaybackRate, +// ), +// new Text( +// '1_5', +// style: TextStyle(color: Colors.blue), +// ), +// new Radio( +// value: PlaybackRate.RATE_2, +// groupValue: _playbackRate, +// onChanged: _changePlaybackRate, +// ), +// new Text( +// '2', +// style: TextStyle(color: Colors.blue), +// ) +// ], +// ); +// } +// } \ No newline at end of file diff --git a/lib/videos/players/YoutubeDefaultWidget.dart b/lib/videos/players/YoutubeDefaultWidget.dart new file mode 100644 index 0000000..e4183f0 --- /dev/null +++ b/lib/videos/players/YoutubeDefaultWidget.dart @@ -0,0 +1,90 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter_youtube_view/flutter_youtube_view.dart'; + +// class YoutubeDefaultWidget extends StatefulWidget { +// final String id; +// YoutubeDefaultWidget({this.id}); +// @override +// _MyAppState createState() => _MyAppState(); +// } + +// class _MyAppState extends State +// implements YouTubePlayerListener { +// //double _currentVideoSecond = 0.0; +// //String _playerState = ""; +// //FlutterYoutubeViewController _controller; + +// @override +// void onCurrentSecond(double second) { +// // print("onCurrentSecond second = $second"); +// // _currentVideoSecond = second; +// } + +// @override +// void onError(String error) { +// print("onError error = $error"); +// } + +// @override +// void onReady() { +// print("onReady"); +// } + +// @override +// void onStateChange(String state) { +// // print("onStateChange state = $state"); +// // setState(() { +// // _playerState = state; +// // }); +// } + +// @override +// void onVideoDuration(double duration) { +// print("onVideoDuration duration = $duration"); +// } + +// void _onYoutubeCreated(FlutterYoutubeViewController controller) { +// //this._controller = controller; +// } + +// // void _loadOrCueVideo() { +// // _controller.loadOrCueVideo('gcj2RUWQZ60', _currentVideoSecond); +// // } + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar(), +// body: Stack( +// children: [ +// AspectRatio( +// aspectRatio: 16/9, +// child: FlutterYoutubeView( +// onViewCreated: _onYoutubeCreated, +// listener: this, +// params: YoutubeParam( +// videoId: widget.id, +// showUI: true, +// //startSeconds: 5 * 60.0, +// autoPlay: true, +// showYoutube: false, +// showFullScreen: true, +// ), +// )), +// // Center( +// // child: Column( +// // children: [ +// // Text( +// // 'Current state: $_playerState', +// // style: TextStyle(color: Colors.blue), +// // ), +// // RaisedButton( +// // onPressed: _loadOrCueVideo, +// // child: Text('Click reload video'), +// // ), +// // ], +// // )) +// ], +// )); +// } +// } \ No newline at end of file diff --git a/lib/videos/youtube_video_player.dart b/lib/videos/youtube_video_player.dart new file mode 100644 index 0000000..9b4e9e3 --- /dev/null +++ b/lib/videos/youtube_video_player.dart @@ -0,0 +1,76 @@ +import 'package:flutter/material.dart'; +import 'package:youtube_player_flutter/youtube_player_flutter.dart'; + +import 'api/youtube_classes.dart'; + +class YouTubeVideoPlayerScreen extends StatefulWidget { + final YouTubeItems ytVideo; + YouTubeVideoPlayerScreen({@required this.ytVideo}); + @override + _YouTubeVideoPlayerScreenState createState() => _YouTubeVideoPlayerScreenState(); +} + +class _YouTubeVideoPlayerScreenState extends State { + + YoutubePlayerController _controller; + bool _fullScreen = false; + @override + void initState() { + super.initState(); + _controller = new YoutubePlayerController(initialVideoId: widget.ytVideo.id.videoId); + } + + @override + void dispose() { + //_controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + //appBar: AppBar(), + body: SafeArea( + child: YoutubePlayerBuilder( + player: YoutubePlayer( + controller: _controller, + topActions: [ + IconButton(icon: Icon(Icons.close),onPressed: (){ + if(this._fullScreen){ + _controller.toggleFullScreenMode(); + } + else{ + Navigator.of(context).pop(); + } + }), + ], + ), + onEnterFullScreen: (){ + this._fullScreen = true; + }, + onExitFullScreen: ()=>this._fullScreen = false, + builder: (context,player){ + return Column( + children: [ + player, + Expanded( + child: SingleChildScrollView( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + Text(widget.ytVideo.snippet.title), + SizedBox(height: 10.0,), + Text(widget.ytVideo.snippet.description), + ], + ), + ) + ), + + ], + ); + }, + ), + ) + ); + } +} \ No newline at end of file diff --git a/lib/videos/youtube_videos.dart b/lib/videos/youtube_videos.dart new file mode 100644 index 0000000..bd09f46 --- /dev/null +++ b/lib/videos/youtube_videos.dart @@ -0,0 +1,324 @@ +import 'package:appcardsstarter/videos/youtube_video_player.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_staggered_animations/flutter_staggered_animations.dart'; +import 'package:get/get.dart'; +import 'package:transparent_image/transparent_image.dart'; + +//import 'players/YoutubeCustomWidget.dart'; +import 'api/youtube_classes.dart'; +import 'bloc/youtube_controller.dart'; +//import 'players/YoutubeDefaultWidget.dart'; + +// class YouTubeVideosScreen extends StatelessWidget { +// final YouTubeController c = Get.put(YouTubeController()); + +// @override +// Widget build(BuildContext context) { +// return Scaffold( +// appBar: AppBar( +// title: Text('Vídeos'), +// ), +// body: Obx(() => c.loading.value ? Center(child: CircularProgressIndicator(),) : c.errorCode.value != 0 ? this._buildError() : RefreshIndicator( +// onRefresh: c.refresh, +// child: AnimationLimiter( +// child: ListView.builder( +// padding: const EdgeInsets.all(8.0), +// itemCount: c.itens.length + 1, +// itemBuilder: (_,index){ +// if (index < c.itens.length) { +// var item = c.itens[index]; +// return AnimationConfiguration.staggeredList( +// position: index, +// duration: const Duration(milliseconds: 375), +// child: SlideAnimation( +// verticalOffset: 30.0, +// child: FadeInAnimation( +// child: listItem(item), +// ) +// ) +// ); +// // return SlideTransition( +// // position: c.animation, +// // child: this._buildListTile(index) +// // ); +// } else if (index > 1) { +// if (!GetUtils.isNullOrBlank(c.results.value.nextPageToken)) { +// c.getChannelVideosBloc(); +// return Center(child: CircularProgressIndicator(),); +// } else { +// return Center( +// child: Padding( +// padding: const EdgeInsets.only(top: 8.0,bottom: 25.0), +// child: +// Text("Não há mais Vídeos para exibir."), +// ), +// ); +// } +// } +// else { +// return Center(child: Padding( +// padding: const EdgeInsets.only(top: 8.0), +// child: Text("Não há mais Vídeos para exibir."), +// ),); +// } +// }, +// ), +// ), +// )), +// ); +// } + +// Widget listItem(YouTubeItems item) { +// return InkWell( +// onTap: (){ +// showModalBottomSheet(context: Get.context, builder: (_)=>Container( +// child: Column( +// children: [ +// ListTile( +// title: Text('Player 1'), +// onTap: (){ +// Get.to(() => YouTubeVideoPlayerScreen(ytVideo: item,)); +// }, +// ), +// // ListTile( +// // title: Text('Player 2 - YoutubeDefaultWidget'), +// // onTap: (){ +// // Navigator.of(context).push(MaterialPageRoute(builder: (_)=>YoutubeDefaultWidget(id: item.id.videoId))); +// // }, +// // ), +// // ListTile( +// // title: Text('Player 3 - YoutubeCustomWidget'), +// // onTap: (){ +// // Navigator.of(context).push(MaterialPageRoute(builder: (_)=>YoutubeCustomWidget())); +// // }, +// // ), +// // ListTile( +// // title: Text('Player 3 - API key'), +// // onTap: (){ +// // FlutterYoutube.playYoutubeVideoById( +// // apiKey:FuncoesGerais.youtubeApiKey, +// // videoId: item.id.videoId, +// // autoPlay: true, //default falase +// // fullScreen: true //default false +// // ); +// // }, +// // ) +// ], +// ), +// )); +// }, +// child: Card( +// elevation: 0, +// color: Colors.transparent, +// child: Container( +// //margin: EdgeInsets.only(bottom: 8.0), +// child: Row( +// children: [ +// LimitedBox( +// maxHeight: 100.0, +// child: AspectRatio( +// aspectRatio: 4/3, +// child: FadeInImage.memoryNetwork( +// placeholder: kTransparentImage, +// image: item.snippet?.thumbnails?.thumbDefault?.url ?? '', +// fit: BoxFit.cover, +// ), +// ), +// ), +// Padding(padding: EdgeInsets.only(right: 10.0)), +// Expanded( +// child: Column( +// mainAxisAlignment: MainAxisAlignment.start, +// crossAxisAlignment: CrossAxisAlignment.start, +// children: [ +// Text( +// item.snippet.title, +// softWrap: true, +// maxLines: 2, +// style: TextStyle(fontSize: 13.0,fontWeight: FontWeight.bold), +// ), +// Padding(padding: EdgeInsets.only(bottom: 1.5)), +// Text( +// item.snippet.description, +// softWrap: true, +// maxLines: 3, +// style: TextStyle(fontSize: 11.0,fontWeight: FontWeight.w400), +// ), +// Padding(padding: EdgeInsets.only(bottom: 3.0)), +// Text( +// item.snippet.publishedAt, +// softWrap: true, +// maxLines: 1, +// style: TextStyle(fontSize: 9.0,fontWeight: FontWeight.w300), +// ), +// ])) +// ], +// ), +// ), +// ), +// ); +// } + +// Widget _buildError(){ +// return Column( +// mainAxisAlignment: MainAxisAlignment.center, +// crossAxisAlignment: CrossAxisAlignment.center, +// children: [ +// Text(c.errorMessage), +// RaisedButton(onPressed: c.refresh, child: Text('Atualizar'),) +// ], +// ); +// } +// } + +class YouTubeVideosScreen extends StatefulWidget { + @override + _YouTubeVideosScreenState createState() => _YouTubeVideosScreenState(); +} + +class _YouTubeVideosScreenState extends State with AutomaticKeepAliveClientMixin { + + final YouTubeController c = Get.put(YouTubeController()); + + @override + void initState() { + super.initState(); + } + + @override + bool get wantKeepAlive => true; + + @override + Widget build(BuildContext context) { + super.build(context); + return Scaffold( + appBar: AppBar( + title: Text('Vídeos'), + ), + body: Obx(() => c.loading.value ? Center(child: CircularProgressIndicator(),) : c.errorCode.value != 0 ? this._buildError() : RefreshIndicator( + onRefresh: c.refresh, + child: AnimationLimiter( + child: ListView.builder( + padding: const EdgeInsets.all(8.0), + itemCount: c.itens.length + 1, + itemBuilder: (_,index){ + if (index < c.itens.length) { + var item = c.itens[index]; + return AnimationConfiguration.staggeredList( + position: index, + duration: const Duration(milliseconds: 375), + child: SlideAnimation( + verticalOffset: 30.0, + child: FadeInAnimation( + child: listItem(item), + ) + ) + ); + // return SlideTransition( + // position: c.animation, + // child: this._buildListTile(index) + // ); + } else if (index > 1) { + if (!GetUtils.isNullOrBlank(c.results.value.nextPageToken)) { + c.getChannelVideosBloc(); + return Center(child: CircularProgressIndicator(),); + } else { + return Center( + child: Padding( + padding: const EdgeInsets.only(top: 8.0,bottom: 25.0), + child: + Text("Não há mais Vídeos para exibir."), + ), + ); + } + } + else { + return Center(child: Padding( + padding: const EdgeInsets.only(top: 8.0), + child: Text("Não há mais Vídeos para exibir."), + ),); + } + }, + ), + ), + )), + ); + } + + Widget listItem(YouTubeItems item) { + return InkWell( + onTap: (){ + if(GetUtils.isNullOrBlank(item.id.videoId)){ + Get.rawSnackbar(message: 'Não foi possível reproduzir o vídeo'); + } + else{ + Get.to(() => YouTubeVideoPlayerScreen(ytVideo: item,)); + } + + }, + child: Card( + elevation: 0, + color: Colors.transparent, + child: Container( + //margin: EdgeInsets.only(bottom: 8.0), + child: Row( + children: [ + LimitedBox( + maxHeight: 100.0, + child: AspectRatio( + aspectRatio: 4/3, + child: FadeInImage.memoryNetwork( + placeholder: kTransparentImage, + image: item.snippet?.thumbnails?.thumbDefault?.url ?? '', + fit: BoxFit.cover, + ), + ), + ), + Padding(padding: EdgeInsets.only(right: 10.0)), + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.snippet.title, + softWrap: true, + maxLines: 2, + style: TextStyle(fontSize: 13.0,fontWeight: FontWeight.bold), + ), + Padding(padding: EdgeInsets.only(bottom: 1.5)), + Text( + item.snippet.description, + softWrap: true, + maxLines: 3, + style: TextStyle(fontSize: 11.0,fontWeight: FontWeight.w400), + ), + Padding(padding: EdgeInsets.only(bottom: 3.0)), + Text( + c.getDateFormatada(item.snippet.publishedAt), + softWrap: true, + maxLines: 1, + style: TextStyle(fontSize: 9.0,fontWeight: FontWeight.w300), + ), + ])) + ], + ), + ), + ), + ); + } + + Widget _buildError(){ + return Container( + width: double.maxFinite, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Text(c.errorMessage), + RaisedButton(onPressed: c.refresh, child: Text('Atualizar'),) + ], + ), + ); + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock new file mode 100644 index 0000000..b777d96 --- /dev/null +++ b/pubspec.lock @@ -0,0 +1,654 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + animated_splash_screen: + dependency: "direct main" + description: + name: animated_splash_screen + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1+2" + animations: + dependency: "direct main" + description: + name: animations + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.5.0-nullsafety.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0-nullsafety.1" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.3" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + chewie: + dependency: transitive + description: + name: chewie + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.2" + chewie_audio: + dependency: transitive + description: + name: chewie_audio + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + circular_reveal_animation: + dependency: "direct main" + description: + name: circular_reveal_animation + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.5" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.15.0-nullsafety.3" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + convex_bottom_bar: + dependency: "direct main" + description: + name: convex_bottom_bar + url: "https://pub.dartlang.org" + source: hosted + version: "2.7.1+2" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + css_colors: + dependency: transitive + description: + name: css_colors + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.2" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + device_info: + dependency: "direct main" + description: + name: device_info + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + device_info_platform_interface: + dependency: transitive + description: + name: device_info_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + ffi: + dependency: transitive + description: + name: ffi + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "5.2.1" + firebase_messaging: + dependency: "direct main" + description: + name: firebase_messaging + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.16" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_html: + dependency: "direct main" + description: + name: flutter_html + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + flutter_inappwebview: + dependency: transitive + description: + name: flutter_inappwebview + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0+4" + flutter_layout_grid: + dependency: transitive + description: + name: flutter_layout_grid + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.5" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_staggered_animations: + dependency: "direct main" + description: + name: flutter_staggered_animations + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" + flutter_svg: + dependency: transitive + description: + name: flutter_svg + url: "https://pub.dartlang.org" + source: hosted + version: "0.19.1" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + get: + dependency: "direct main" + description: + name: get + url: "https://pub.dartlang.org" + source: hosted + version: "3.26.0" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.0+4" + http: + dependency: "direct main" + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.2" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.4" + import_js_library: + dependency: transitive + description: + name: import_js_library + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + intl: + dependency: transitive + description: + name: intl + url: "https://pub.dartlang.org" + source: hosted + version: "0.16.1" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.2" + line_icons: + dependency: "direct main" + description: + name: line_icons + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.10-nullsafety.1" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0-nullsafety.3" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7" + page_transition: + dependency: transitive + description: + name: page_transition + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.7+6" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0-nullsafety.1" + path_drawing: + dependency: transitive + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "0.4.1+1" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+2" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.4+3" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.2" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + platform: + dependency: transitive + description: + name: platform + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.1" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + process: + dependency: transitive + description: + name: process + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.13" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.5" + sa_v1_migration: + dependency: transitive + description: + name: sa_v1_migration + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + url: "https://pub.dartlang.org" + source: hosted + version: "0.5.12+4" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2+4" + shared_preferences_macos: + dependency: transitive + description: + name: shared_preferences_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+11" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2+7" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.2+3" + simple_animations: + dependency: "direct main" + description: + name: simple_animations + url: "https://pub.dartlang.org" + source: hosted + version: "2.5.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.8.0-nullsafety.2" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0-nullsafety.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0-nullsafety.1" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety.1" + supercharged: + dependency: "direct main" + description: + name: supercharged + url: "https://pub.dartlang.org" + source: hosted + version: "1.12.0" + supercharged_dart: + dependency: transitive + description: + name: supercharged_dart + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0-nullsafety.1" + test_api: + dependency: transitive + description: + name: test_api + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.19-nullsafety.2" + transparent_image: + dependency: "direct main" + description: + name: transparent_image + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0-nullsafety.3" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + url: "https://pub.dartlang.org" + source: hosted + version: "5.7.10" + url_launcher_linux: + dependency: transitive + description: + name: url_launcher_linux + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+4" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+9" + url_launcher_platform_interface: + dependency: transitive + description: + name: url_launcher_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.9" + url_launcher_web: + dependency: transitive + description: + name: url_launcher_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.5+3" + url_launcher_windows: + dependency: transitive + description: + name: url_launcher_windows + url: "https://pub.dartlang.org" + source: hosted + version: "0.0.1+3" + uuid: + dependency: transitive + description: + name: uuid + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.2" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0-nullsafety.3" + video_player: + dependency: transitive + description: + name: video_player + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + video_player_platform_interface: + dependency: transitive + description: + name: video_player_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + video_player_web: + dependency: transitive + description: + name: video_player_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.4+1" + wakelock: + dependency: transitive + description: + name: wakelock + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.1+1" + wakelock_platform_interface: + dependency: transitive + description: + name: wakelock_platform_interface + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0+1" + wakelock_web: + dependency: transitive + description: + name: wakelock_web + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0+3" + webview_flutter: + dependency: "direct main" + description: + name: webview_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.7" + win32: + dependency: transitive + description: + name: win32 + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.4+1" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.1" + youtube_player_flutter: + dependency: "direct main" + description: + name: youtube_player_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "7.0.0+7" +sdks: + dart: ">=2.10.0-110 <2.11.0" + flutter: ">=1.22.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml new file mode 100644 index 0000000..19283e2 --- /dev/null +++ b/pubspec.yaml @@ -0,0 +1,97 @@ +name: appcardsstarter +description: A new Flutter project. + +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ">=2.7.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.0 + webview_flutter: ^1.0.7 + convex_bottom_bar: ^2.7.1+2 + http: ^0.12.2 + transparent_image: ^1.0.0 + flutter_staggered_animations: ^0.1.3 + simple_animations: ^2.5.1 + circular_reveal_animation: ^1.1.5 + supercharged: ^1.12.0 + url_launcher: ^5.7.10 + flutter_html: ^1.2.0 + device_info: ^1.0.0 + firebase_messaging: 6.0.16 + get: ^3.26.0 + line_icons: ^1.3.2 + animated_splash_screen: ^1.0.1+2 + animations: ^1.1.2 + shared_preferences: ^0.5.12+4 + youtube_player_flutter: ^7.0.0+7 + +dev_dependencies: + flutter_test: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + assets: + - assets/images/ + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/test/widget_test.dart b/test/widget_test.dart new file mode 100644 index 0000000..5e0a0bc --- /dev/null +++ b/test/widget_test.dart @@ -0,0 +1,29 @@ +// This is a basic Flutter widget test. +// +// To perform an interaction with a widget in your test, use the WidgetTester +// utility that Flutter provides. For example, you can send tap and scroll +// gestures. You can also use WidgetTester to find child widgets in the widget +// tree, read text, and verify that the values of widget properties are correct. + +import 'package:appcardsstarter/splash/splash.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(SplashScreen()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +}