commit 76d5d0941b2ecc27c9732a965039377e2cf61b4f
Author: zy <240495820@qq.com>
Date: Fri Sep 12 14:19:13 2025 +0800
init
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..79c113f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,45 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.build/
+.buildlog/
+.history
+.svn/
+.swiftpm/
+migrate_working_dir/
+
+# 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
+.pub-cache/
+.pub/
+/build/
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/.metadata b/.metadata
new file mode 100644
index 0000000..9876868
--- /dev/null
+++ b/.metadata
@@ -0,0 +1,33 @@
+# 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: "6fba2447e95c451518584c35e25f5433f14d888c"
+ channel: "stable"
+
+project_type: app
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: 6fba2447e95c451518584c35e25f5433f14d888c
+ base_revision: 6fba2447e95c451518584c35e25f5433f14d888c
+ - platform: android
+ create_revision: 6fba2447e95c451518584c35e25f5433f14d888c
+ base_revision: 6fba2447e95c451518584c35e25f5433f14d888c
+ - platform: ios
+ create_revision: 6fba2447e95c451518584c35e25f5433f14d888c
+ base_revision: 6fba2447e95c451518584c35e25f5433f14d888c
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..12be715
--- /dev/null
+++ b/README.md
@@ -0,0 +1,71 @@
+# kinetra
+
+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://docs.flutter.dev/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev/), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
+
+包名:com.kinetra.adehok.app
+
+# 修改app名称
+https://pub.dev/packages/rename
+- 1.activate
+ flutter pub global activate rename
+- 2.Set AppName
+ flutter pub global run rename setAppName --targets ios,android --value "Kinetra"
+- 3.Set BundleId
+ flutter pub global run rename setBundleId --targets ios,android --value "com.kinetra.adehok.app"
+
+# 修改启动图标
+https://pub.dev/packages/flutter_launcher_icons
+- 1. Setup the config file
+ dart run flutter_launcher_icons:generate
+- 2. Run the package
+ dart run flutter_launcher_icons
+
+# 更改系统启动页
+https://pub.dev/packages/flutter_native_splash
+- 1. 新建/编辑 flutter_native_splash.yaml
+- 2. Run the package
+ dart run flutter_native_splash:create
+
+# 生成安卓打包证书
+keytool -genkeypair -v -keystore kinetra_adehok_app.jks -keyalg RSA -keysize 2048 -validity 10000 -alias com.kinetra.adehok.app
+口令:123456@nyxora
+
+# 查看安卓证书指纹
+keytool -list -v -keystore kinetra_adehok_app.jks
+
+别名: com.kinetra.adehok.app
+创建日期: 2025年8月20日
+条目类型: PrivateKeyEntry
+证书链长度: 1
+证书[1]:
+所有者: CN=zy, OU=qj, O=qj, L=cs, ST=hn, C=cn
+发布者: CN=zy, OU=qj, O=qj, L=cs, ST=hn, C=cn
+序列号: 45fb9110ec85ed35
+生效时间: Wed Aug 20 13:44:03 CST 2025, 失效时间: Sun Jan 05 13:44:03 CST 2053
+证书指纹:
+SHA1: E8:3F:DB:87:73:40:A6:0E:BA:43:C5:C5:42:62:D2:95:FA:E0:DA:21
+SHA256: C5:0A:88:AA:B8:1E:C2:0A:6C:64:0E:99:18:4E:97:86:A0:C8:3F:2C:98:EE:E9:97:6A:A2:CC:B0:03:70:EE:56
+签名算法名称: SHA384withRSA
+主体公共密钥算法: 2048 位 RSA 密钥
+版本: 3
+
+# 监听model修改,自动生成
+dart run build_runner watch --delete-conflicting-outputs
+
+# 打包
+正式包: flutter build apk --release
+aab的包: flutter build appbundle
+iOS: flutter build ipa
\ No newline at end of file
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..0d29021
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,28 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at https://dart.dev/lints.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100755
index 0000000..be3943c
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,14 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+.cxx/
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/to/reference-keystore
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
new file mode 100644
index 0000000..7bfda37
--- /dev/null
+++ b/android/app/build.gradle.kts
@@ -0,0 +1,62 @@
+plugins {
+ id("com.android.application")
+ id("kotlin-android")
+ // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
+ id("dev.flutter.flutter-gradle-plugin")
+}
+
+android {
+ namespace = "com.kinetra.adehok.app"
+ compileSdk = flutter.compileSdkVersion
+ ndkVersion = "27.0.12077973"
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ isCoreLibraryDesugaringEnabled = true
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_11.toString()
+ }
+
+ defaultConfig {
+ // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
+ applicationId = "com.kinetra.adehok.app"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://flutter.dev/to/review-gradle-config.
+ minSdk = flutter.minSdkVersion
+ targetSdk = flutter.targetSdkVersion
+ versionCode = flutter.versionCode
+ versionName = flutter.versionName
+ }
+
+ 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.getByName("debug")
+ }
+ }
+}
+dependencies {
+ //支持 Kotlin 编写的原生代码
+ implementation("org.jetbrains.kotlin:kotlin-stdlib:1.6.10")
+ // 支持方法数超过 65536 的项目
+ implementation("com.android.support:multidex:1.0.3")
+ implementation("com.google.android.exoplayer:exoplayer:2.19.1")
+// // firebase相关:推送通知
+// implementation("com.google.firebase:firebase-messaging:23.1.2")
+// // firebase相关:行为统计
+// implementation("com.google.firebase:firebase-analytics:21.2.2")
+// // firebase相关:崩溃日志上报
+// implementation("com.google.firebase:firebase-crashlytics:18.3.7")
+// // firebase相关:用于识别设备实例 ID
+// implementation("com.google.firebase:firebase-iid:21.1.0")
+// implementation("com.android.installreferrer:installreferrer:2.2")
+// // firebase相关:添加核心库 coreLibraryDesugaring 依赖
+ coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
+}
+flutter {
+ source = "../.."
+}
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000..399f698
--- /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..fcfd475
--- /dev/null
+++ b/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/kotlin/com/kinetra/adehok/app/MainActivity.kt b/android/app/src/main/kotlin/com/kinetra/adehok/app/MainActivity.kt
new file mode 100644
index 0000000..a5107a8
--- /dev/null
+++ b/android/app/src/main/kotlin/com/kinetra/adehok/app/MainActivity.kt
@@ -0,0 +1,26 @@
+package com.kinetra.adehok.app
+
+import android.os.Bundle
+import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.plugin.common.MethodChannel
+
+class MainActivity: FlutterActivity() {
+ private val CHANNEL = "backChannel"
+
+ override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
+ super.configureFlutterEngine(flutterEngine)
+
+ MethodChannel(
+ flutterEngine.dartExecutor.binaryMessenger,
+ CHANNEL
+ ).setMethodCallHandler { call, result ->
+ if (call.method == "moveToBack") {
+ moveTaskToBack(true)
+ result.success(null)
+ } else {
+ result.notImplemented()
+ }
+ }
+ }
+}
diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100755
index 0000000..f74085f
--- /dev/null
+++ b/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
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 100755
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 100755
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 100755
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 100755
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 100755
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 100755
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-night/styles.xml b/android/app/src/main/res/values-night/styles.xml
new file mode 100755
index 0000000..06952be
--- /dev/null
+++ b/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
new file mode 100755
index 0000000..cb1ef88
--- /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..399f698
--- /dev/null
+++ b/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/android/build.gradle.kts b/android/build.gradle.kts
new file mode 100644
index 0000000..89176ef
--- /dev/null
+++ b/android/build.gradle.kts
@@ -0,0 +1,21 @@
+allprojects {
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+
+val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
+rootProject.layout.buildDirectory.value(newBuildDir)
+
+subprojects {
+ val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
+ project.layout.buildDirectory.value(newSubprojectBuildDir)
+}
+subprojects {
+ project.evaluationDependsOn(":app")
+}
+
+tasks.register("clean") {
+ delete(rootProject.layout.buildDirectory)
+}
diff --git a/android/gradle.properties b/android/gradle.properties
new file mode 100644
index 0000000..f018a61
--- /dev/null
+++ b/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..348c409
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip
diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts
new file mode 100644
index 0000000..ab39a10
--- /dev/null
+++ b/android/settings.gradle.kts
@@ -0,0 +1,25 @@
+pluginManagement {
+ val flutterSdkPath = run {
+ val properties = java.util.Properties()
+ file("local.properties").inputStream().use { properties.load(it) }
+ val flutterSdkPath = properties.getProperty("flutter.sdk")
+ require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
+ flutterSdkPath
+ }
+
+ includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
+
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+
+plugins {
+ id("dev.flutter.flutter-plugin-loader") version "1.0.0"
+ id("com.android.application") version "8.7.3" apply false
+ id("org.jetbrains.kotlin.android") version "2.1.0" apply false
+}
+
+include(":app")
diff --git a/assets/bg1.png b/assets/bg1.png
new file mode 100644
index 0000000..56f219d
Binary files /dev/null and b/assets/bg1.png differ
diff --git a/assets/bg2.png b/assets/bg2.png
new file mode 100644
index 0000000..3cc4ed8
Binary files /dev/null and b/assets/bg2.png differ
diff --git a/assets/home_desc_bg.png b/assets/home_desc_bg.png
new file mode 100644
index 0000000..84c78f0
Binary files /dev/null and b/assets/home_desc_bg.png differ
diff --git a/assets/home_left.png b/assets/home_left.png
new file mode 100644
index 0000000..3fdf58e
Binary files /dev/null and b/assets/home_left.png differ
diff --git a/assets/home_left_sel.png b/assets/home_left_sel.png
new file mode 100644
index 0000000..204d694
Binary files /dev/null and b/assets/home_left_sel.png differ
diff --git a/assets/home_right.png b/assets/home_right.png
new file mode 100644
index 0000000..918a5a4
Binary files /dev/null and b/assets/home_right.png differ
diff --git a/assets/home_right_sel.png b/assets/home_right_sel.png
new file mode 100644
index 0000000..4826d95
Binary files /dev/null and b/assets/home_right_sel.png differ
diff --git a/assets/home_top.png b/assets/home_top.png
new file mode 100644
index 0000000..7a96ad1
Binary files /dev/null and b/assets/home_top.png differ
diff --git a/assets/home_top_slogan.png b/assets/home_top_slogan.png
new file mode 100644
index 0000000..0ecf099
Binary files /dev/null and b/assets/home_top_slogan.png differ
diff --git a/assets/ic_about_us.png b/assets/ic_about_us.png
new file mode 100644
index 0000000..c27f62d
Binary files /dev/null and b/assets/ic_about_us.png differ
diff --git a/assets/ic_agreement.png b/assets/ic_agreement.png
new file mode 100644
index 0000000..bbdfdad
Binary files /dev/null and b/assets/ic_agreement.png differ
diff --git a/assets/ic_avatar.png b/assets/ic_avatar.png
new file mode 100644
index 0000000..ac0b1c1
Binary files /dev/null and b/assets/ic_avatar.png differ
diff --git a/assets/ic_collect_sel.png b/assets/ic_collect_sel.png
new file mode 100644
index 0000000..1de35ce
Binary files /dev/null and b/assets/ic_collect_sel.png differ
diff --git a/assets/ic_collect_unsel.png b/assets/ic_collect_unsel.png
new file mode 100644
index 0000000..bb71cb0
Binary files /dev/null and b/assets/ic_collect_unsel.png differ
diff --git a/assets/ic_dec.png b/assets/ic_dec.png
new file mode 100644
index 0000000..2d841db
Binary files /dev/null and b/assets/ic_dec.png differ
diff --git a/assets/ic_delete.png b/assets/ic_delete.png
new file mode 100644
index 0000000..81745de
Binary files /dev/null and b/assets/ic_delete.png differ
diff --git a/assets/ic_explore_sel.png b/assets/ic_explore_sel.png
new file mode 100644
index 0000000..383ba01
Binary files /dev/null and b/assets/ic_explore_sel.png differ
diff --git a/assets/ic_explore_unsel.png b/assets/ic_explore_unsel.png
new file mode 100644
index 0000000..4e80ad9
Binary files /dev/null and b/assets/ic_explore_unsel.png differ
diff --git a/assets/ic_favorite_sel.png b/assets/ic_favorite_sel.png
new file mode 100644
index 0000000..317f4e8
Binary files /dev/null and b/assets/ic_favorite_sel.png differ
diff --git a/assets/ic_favorite_unsel.png b/assets/ic_favorite_unsel.png
new file mode 100644
index 0000000..7a404a5
Binary files /dev/null and b/assets/ic_favorite_unsel.png differ
diff --git a/assets/ic_help_center.png b/assets/ic_help_center.png
new file mode 100644
index 0000000..ba3172b
Binary files /dev/null and b/assets/ic_help_center.png differ
diff --git a/assets/ic_home_eposide.png b/assets/ic_home_eposide.png
new file mode 100644
index 0000000..1096460
Binary files /dev/null and b/assets/ic_home_eposide.png differ
diff --git a/assets/ic_home_play.png b/assets/ic_home_play.png
new file mode 100644
index 0000000..7aff800
Binary files /dev/null and b/assets/ic_home_play.png differ
diff --git a/assets/ic_home_play_green.png b/assets/ic_home_play_green.png
new file mode 100644
index 0000000..8d0521c
Binary files /dev/null and b/assets/ic_home_play_green.png differ
diff --git a/assets/ic_home_sel.png b/assets/ic_home_sel.png
new file mode 100644
index 0000000..51df5bf
Binary files /dev/null and b/assets/ic_home_sel.png differ
diff --git a/assets/ic_home_unsel.png b/assets/ic_home_unsel.png
new file mode 100644
index 0000000..16bf3bf
Binary files /dev/null and b/assets/ic_home_unsel.png differ
diff --git a/assets/ic_hot.png b/assets/ic_hot.png
new file mode 100644
index 0000000..41f3f9d
Binary files /dev/null and b/assets/ic_hot.png differ
diff --git a/assets/ic_language.png b/assets/ic_language.png
new file mode 100644
index 0000000..f8eac29
Binary files /dev/null and b/assets/ic_language.png differ
diff --git a/assets/ic_mine_sel.png b/assets/ic_mine_sel.png
new file mode 100644
index 0000000..5b7b7d4
Binary files /dev/null and b/assets/ic_mine_sel.png differ
diff --git a/assets/ic_mine_unsel.png b/assets/ic_mine_unsel.png
new file mode 100644
index 0000000..418e46b
Binary files /dev/null and b/assets/ic_mine_unsel.png differ
diff --git a/assets/ic_privacy.png b/assets/ic_privacy.png
new file mode 100644
index 0000000..bf6020a
Binary files /dev/null and b/assets/ic_privacy.png differ
diff --git a/assets/ic_right.png b/assets/ic_right.png
new file mode 100644
index 0000000..0a92328
Binary files /dev/null and b/assets/ic_right.png differ
diff --git a/assets/ic_right_arr.png b/assets/ic_right_arr.png
new file mode 100644
index 0000000..df11e34
Binary files /dev/null and b/assets/ic_right_arr.png differ
diff --git a/assets/ic_search.png b/assets/ic_search.png
new file mode 100644
index 0000000..239d74c
Binary files /dev/null and b/assets/ic_search.png differ
diff --git a/assets/ic_splash_btn.png b/assets/ic_splash_btn.png
new file mode 100644
index 0000000..b251db2
Binary files /dev/null and b/assets/ic_splash_btn.png differ
diff --git a/assets/ic_star.png b/assets/ic_star.png
new file mode 100644
index 0000000..2478a95
Binary files /dev/null and b/assets/ic_star.png differ
diff --git a/assets/ip.png b/assets/ip.png
new file mode 100644
index 0000000..c56ceae
Binary files /dev/null and b/assets/ip.png differ
diff --git a/assets/mine_refill_bg.png b/assets/mine_refill_bg.png
new file mode 100644
index 0000000..9b002c0
Binary files /dev/null and b/assets/mine_refill_bg.png differ
diff --git a/assets/mine_top_bg.png b/assets/mine_top_bg.png
new file mode 100644
index 0000000..2a26f6d
Binary files /dev/null and b/assets/mine_top_bg.png differ
diff --git a/assets/placeholder.png b/assets/placeholder.png
new file mode 100644
index 0000000..1a96ae1
Binary files /dev/null and b/assets/placeholder.png differ
diff --git a/assets/splash_bg.png b/assets/splash_bg.png
new file mode 100644
index 0000000..4801ac9
Binary files /dev/null and b/assets/splash_bg.png differ
diff --git a/assets/splash_bg2.png b/assets/splash_bg2.png
new file mode 100644
index 0000000..77fe9c5
Binary files /dev/null and b/assets/splash_bg2.png differ
diff --git a/assets/text_bg.png b/assets/text_bg.png
new file mode 100644
index 0000000..606563e
Binary files /dev/null and b/assets/text_bg.png differ
diff --git a/devtools_options.yaml b/devtools_options.yaml
new file mode 100644
index 0000000..fa0b357
--- /dev/null
+++ b/devtools_options.yaml
@@ -0,0 +1,3 @@
+description: This file stores settings for Dart & Flutter DevTools.
+documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
+extensions:
diff --git a/ios/.gitignore b/ios/.gitignore
new file mode 100755
index 0000000..7a7f987
--- /dev/null
+++ b/ios/.gitignore
@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
new file mode 100755
index 0000000..7c56964
--- /dev/null
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,26 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+ MinimumOSVersion
+ 12.0
+
+
diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig
new file mode 100755
index 0000000..ec97fc6
--- /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 100755
index 0000000..c4855bf
--- /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 100755
index 0000000..e549ee2
--- /dev/null
+++ b/ios/Podfile
@@ -0,0 +1,43 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '12.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+ use_frameworks!
+
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+ target 'RunnerTests' do
+ inherit! :search_paths
+ end
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_ios_build_settings(target)
+ end
+end
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
new file mode 100644
index 0000000..82efc7c
--- /dev/null
+++ b/ios/Podfile.lock
@@ -0,0 +1,480 @@
+PODS:
+ - Adjust (5.4.1):
+ - Adjust/Adjust (= 5.4.1)
+ - Adjust/Adjust (5.4.1):
+ - AdjustSignature (= 3.47.0)
+ - adjust_sdk (5.4.1):
+ - Adjust (= 5.4.1)
+ - Flutter
+ - AdjustSignature (3.47.0)
+ - advertising_id (0.0.1):
+ - Flutter
+ - app_badge_plus (1.2.3):
+ - Flutter
+ - app_links (6.4.1):
+ - Flutter
+ - app_tracking_transparency (0.0.1):
+ - Flutter
+ - device_info_plus (0.0.1):
+ - Flutter
+ - FBAEMKit (17.0.3):
+ - FBSDKCoreKit_Basics (= 17.0.3)
+ - FBSDKCoreKit (17.0.3):
+ - FBAEMKit (= 17.0.3)
+ - FBSDKCoreKit_Basics (= 17.0.3)
+ - FBSDKCoreKit_Basics (17.0.3)
+ - FBSDKLoginKit (17.0.3):
+ - FBSDKCoreKit (= 17.0.3)
+ - Firebase/Analytics (10.25.0):
+ - Firebase/Core
+ - Firebase/Core (10.25.0):
+ - Firebase/CoreOnly
+ - FirebaseAnalytics (~> 10.25.0)
+ - Firebase/CoreOnly (10.25.0):
+ - FirebaseCore (= 10.25.0)
+ - Firebase/Crashlytics (10.25.0):
+ - Firebase/CoreOnly
+ - FirebaseCrashlytics (~> 10.25.0)
+ - Firebase/Messaging (10.25.0):
+ - Firebase/CoreOnly
+ - FirebaseMessaging (~> 10.25.0)
+ - Firebase/Performance (10.25.0):
+ - Firebase/CoreOnly
+ - FirebasePerformance (~> 10.25.0)
+ - firebase_analytics (10.8.10):
+ - Firebase/Analytics (= 10.25.0)
+ - firebase_core
+ - Flutter
+ - firebase_core (2.32.0):
+ - Firebase/CoreOnly (= 10.25.0)
+ - Flutter
+ - firebase_crashlytics (3.5.7):
+ - Firebase/Crashlytics (= 10.25.0)
+ - firebase_core
+ - Flutter
+ - firebase_messaging (14.7.10):
+ - Firebase/Messaging (= 10.25.0)
+ - firebase_core
+ - Flutter
+ - firebase_performance (0.9.4-7):
+ - Firebase/Performance (= 10.25.0)
+ - firebase_core
+ - Flutter
+ - FirebaseABTesting (10.29.0):
+ - FirebaseCore (~> 10.0)
+ - FirebaseAnalytics (10.25.0):
+ - FirebaseAnalytics/AdIdSupport (= 10.25.0)
+ - FirebaseCore (~> 10.0)
+ - FirebaseInstallations (~> 10.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 7.11)
+ - GoogleUtilities/MethodSwizzler (~> 7.11)
+ - GoogleUtilities/Network (~> 7.11)
+ - "GoogleUtilities/NSData+zlib (~> 7.11)"
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - FirebaseAnalytics/AdIdSupport (10.25.0):
+ - FirebaseCore (~> 10.0)
+ - FirebaseInstallations (~> 10.0)
+ - GoogleAppMeasurement (= 10.25.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 7.11)
+ - GoogleUtilities/MethodSwizzler (~> 7.11)
+ - GoogleUtilities/Network (~> 7.11)
+ - "GoogleUtilities/NSData+zlib (~> 7.11)"
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - FirebaseCore (10.25.0):
+ - FirebaseCoreInternal (~> 10.0)
+ - GoogleUtilities/Environment (~> 7.12)
+ - GoogleUtilities/Logger (~> 7.12)
+ - FirebaseCoreExtension (10.29.0):
+ - FirebaseCore (~> 10.0)
+ - FirebaseCoreInternal (10.29.0):
+ - "GoogleUtilities/NSData+zlib (~> 7.8)"
+ - FirebaseCrashlytics (10.25.0):
+ - FirebaseCore (~> 10.5)
+ - FirebaseInstallations (~> 10.0)
+ - FirebaseRemoteConfigInterop (~> 10.23)
+ - FirebaseSessions (~> 10.5)
+ - GoogleDataTransport (~> 9.2)
+ - GoogleUtilities/Environment (~> 7.8)
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - PromisesObjC (~> 2.1)
+ - FirebaseInstallations (10.29.0):
+ - FirebaseCore (~> 10.0)
+ - GoogleUtilities/Environment (~> 7.8)
+ - GoogleUtilities/UserDefaults (~> 7.8)
+ - PromisesObjC (~> 2.1)
+ - FirebaseMessaging (10.25.0):
+ - FirebaseCore (~> 10.0)
+ - FirebaseInstallations (~> 10.0)
+ - GoogleDataTransport (~> 9.3)
+ - GoogleUtilities/AppDelegateSwizzler (~> 7.8)
+ - GoogleUtilities/Environment (~> 7.8)
+ - GoogleUtilities/Reachability (~> 7.8)
+ - GoogleUtilities/UserDefaults (~> 7.8)
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - FirebasePerformance (10.25.0):
+ - FirebaseCore (~> 10.5)
+ - FirebaseInstallations (~> 10.0)
+ - FirebaseRemoteConfig (~> 10.0)
+ - FirebaseSessions (~> 10.5)
+ - GoogleDataTransport (~> 9.2)
+ - GoogleUtilities/Environment (~> 7.13)
+ - GoogleUtilities/ISASwizzler (~> 7.13)
+ - GoogleUtilities/MethodSwizzler (~> 7.13)
+ - GoogleUtilities/UserDefaults (~> 7.13)
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - FirebaseRemoteConfig (10.29.0):
+ - FirebaseABTesting (~> 10.0)
+ - FirebaseCore (~> 10.0)
+ - FirebaseInstallations (~> 10.0)
+ - FirebaseRemoteConfigInterop (~> 10.23)
+ - FirebaseSharedSwift (~> 10.0)
+ - GoogleUtilities/Environment (~> 7.8)
+ - "GoogleUtilities/NSData+zlib (~> 7.8)"
+ - FirebaseRemoteConfigInterop (10.29.0)
+ - FirebaseSessions (10.29.0):
+ - FirebaseCore (~> 10.5)
+ - FirebaseCoreExtension (~> 10.0)
+ - FirebaseInstallations (~> 10.0)
+ - GoogleDataTransport (~> 9.2)
+ - GoogleUtilities/Environment (~> 7.13)
+ - GoogleUtilities/UserDefaults (~> 7.13)
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - PromisesSwift (~> 2.1)
+ - FirebaseSharedSwift (10.29.0)
+ - Flutter (1.0.0)
+ - flutter_facebook_auth (6.2.0):
+ - FBSDKLoginKit (~> 17.0.0)
+ - Flutter
+ - flutter_image_compress_common (1.0.0):
+ - Flutter
+ - Mantle
+ - SDWebImage
+ - SDWebImageWebPCoder
+ - flutter_inappwebview_ios (0.0.1):
+ - Flutter
+ - flutter_inappwebview_ios/Core (= 0.0.1)
+ - OrderedSet (~> 6.0.3)
+ - flutter_inappwebview_ios/Core (0.0.1):
+ - Flutter
+ - OrderedSet (~> 6.0.3)
+ - flutter_local_notifications (0.0.1):
+ - Flutter
+ - flutter_native_splash (2.4.3):
+ - Flutter
+ - flutter_secure_storage (6.0.0):
+ - Flutter
+ - fluttertoast (0.0.2):
+ - Flutter
+ - GoogleAppMeasurement (10.25.0):
+ - GoogleAppMeasurement/AdIdSupport (= 10.25.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 7.11)
+ - GoogleUtilities/MethodSwizzler (~> 7.11)
+ - GoogleUtilities/Network (~> 7.11)
+ - "GoogleUtilities/NSData+zlib (~> 7.11)"
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - GoogleAppMeasurement/AdIdSupport (10.25.0):
+ - GoogleAppMeasurement/WithoutAdIdSupport (= 10.25.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 7.11)
+ - GoogleUtilities/MethodSwizzler (~> 7.11)
+ - GoogleUtilities/Network (~> 7.11)
+ - "GoogleUtilities/NSData+zlib (~> 7.11)"
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - GoogleAppMeasurement/WithoutAdIdSupport (10.25.0):
+ - GoogleUtilities/AppDelegateSwizzler (~> 7.11)
+ - GoogleUtilities/MethodSwizzler (~> 7.11)
+ - GoogleUtilities/Network (~> 7.11)
+ - "GoogleUtilities/NSData+zlib (~> 7.11)"
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - GoogleDataTransport (9.4.1):
+ - GoogleUtilities/Environment (~> 7.7)
+ - nanopb (< 2.30911.0, >= 2.30908.0)
+ - PromisesObjC (< 3.0, >= 1.2)
+ - GoogleUtilities/AppDelegateSwizzler (7.13.3):
+ - GoogleUtilities/Environment
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Network
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Environment (7.13.3):
+ - GoogleUtilities/Privacy
+ - PromisesObjC (< 3.0, >= 1.2)
+ - GoogleUtilities/ISASwizzler (7.13.3):
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Logger (7.13.3):
+ - GoogleUtilities/Environment
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/MethodSwizzler (7.13.3):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Network (7.13.3):
+ - GoogleUtilities/Logger
+ - "GoogleUtilities/NSData+zlib"
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Reachability
+ - "GoogleUtilities/NSData+zlib (7.13.3)":
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Privacy (7.13.3)
+ - GoogleUtilities/Reachability (7.13.3):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/UserDefaults (7.13.3):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - image_picker_ios (0.0.1):
+ - Flutter
+ - in_app_purchase_storekit (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - libwebp (1.5.0):
+ - libwebp/demux (= 1.5.0)
+ - libwebp/mux (= 1.5.0)
+ - libwebp/sharpyuv (= 1.5.0)
+ - libwebp/webp (= 1.5.0)
+ - libwebp/demux (1.5.0):
+ - libwebp/webp
+ - libwebp/mux (1.5.0):
+ - libwebp/demux
+ - libwebp/sharpyuv (1.5.0)
+ - libwebp/webp (1.5.0):
+ - libwebp/sharpyuv
+ - Mantle (2.2.0):
+ - Mantle/extobjc (= 2.2.0)
+ - Mantle/extobjc (2.2.0)
+ - nanopb (2.30910.0):
+ - nanopb/decode (= 2.30910.0)
+ - nanopb/encode (= 2.30910.0)
+ - nanopb/decode (2.30910.0)
+ - nanopb/encode (2.30910.0)
+ - OrderedSet (6.0.3)
+ - package_info_plus (0.4.5):
+ - Flutter
+ - path_provider_foundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - permission_handler_apple (9.3.0):
+ - Flutter
+ - PromisesObjC (2.4.0)
+ - PromisesSwift (2.4.0):
+ - PromisesObjC (= 2.4.0)
+ - SDWebImage (5.21.2):
+ - SDWebImage/Core (= 5.21.2)
+ - SDWebImage/Core (5.21.2)
+ - SDWebImageWebPCoder (0.14.6):
+ - libwebp (~> 1.0)
+ - SDWebImage/Core (~> 5.17)
+ - shared_preferences_foundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - sign_in_with_apple (0.0.1):
+ - Flutter
+ - sqflite_darwin (0.0.4):
+ - Flutter
+ - FlutterMacOS
+ - url_launcher_ios (0.0.1):
+ - Flutter
+ - video_player_avfoundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - wakelock_plus (0.0.1):
+ - Flutter
+ - webview_flutter_wkwebview (0.0.1):
+ - Flutter
+ - FlutterMacOS
+
+DEPENDENCIES:
+ - adjust_sdk (from `.symlinks/plugins/adjust_sdk/ios`)
+ - advertising_id (from `.symlinks/plugins/advertising_id/ios`)
+ - app_badge_plus (from `.symlinks/plugins/app_badge_plus/ios`)
+ - app_links (from `.symlinks/plugins/app_links/ios`)
+ - app_tracking_transparency (from `.symlinks/plugins/app_tracking_transparency/ios`)
+ - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
+ - firebase_analytics (from `.symlinks/plugins/firebase_analytics/ios`)
+ - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
+ - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
+ - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`)
+ - firebase_performance (from `.symlinks/plugins/firebase_performance/ios`)
+ - Flutter (from `Flutter`)
+ - flutter_facebook_auth (from `.symlinks/plugins/flutter_facebook_auth/ios`)
+ - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
+ - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
+ - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`)
+ - flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
+ - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`)
+ - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
+ - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
+ - in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
+ - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
+ - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
+ - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
+ - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
+ - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
+ - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
+ - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
+ - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
+ - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
+ - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
+
+SPEC REPOS:
+ trunk:
+ - Adjust
+ - AdjustSignature
+ - FBAEMKit
+ - FBSDKCoreKit
+ - FBSDKCoreKit_Basics
+ - FBSDKLoginKit
+ - Firebase
+ - FirebaseABTesting
+ - FirebaseAnalytics
+ - FirebaseCore
+ - FirebaseCoreExtension
+ - FirebaseCoreInternal
+ - FirebaseCrashlytics
+ - FirebaseInstallations
+ - FirebaseMessaging
+ - FirebasePerformance
+ - FirebaseRemoteConfig
+ - FirebaseRemoteConfigInterop
+ - FirebaseSessions
+ - FirebaseSharedSwift
+ - GoogleAppMeasurement
+ - GoogleDataTransport
+ - GoogleUtilities
+ - libwebp
+ - Mantle
+ - nanopb
+ - OrderedSet
+ - PromisesObjC
+ - PromisesSwift
+ - SDWebImage
+ - SDWebImageWebPCoder
+
+EXTERNAL SOURCES:
+ adjust_sdk:
+ :path: ".symlinks/plugins/adjust_sdk/ios"
+ advertising_id:
+ :path: ".symlinks/plugins/advertising_id/ios"
+ app_badge_plus:
+ :path: ".symlinks/plugins/app_badge_plus/ios"
+ app_links:
+ :path: ".symlinks/plugins/app_links/ios"
+ app_tracking_transparency:
+ :path: ".symlinks/plugins/app_tracking_transparency/ios"
+ device_info_plus:
+ :path: ".symlinks/plugins/device_info_plus/ios"
+ firebase_analytics:
+ :path: ".symlinks/plugins/firebase_analytics/ios"
+ firebase_core:
+ :path: ".symlinks/plugins/firebase_core/ios"
+ firebase_crashlytics:
+ :path: ".symlinks/plugins/firebase_crashlytics/ios"
+ firebase_messaging:
+ :path: ".symlinks/plugins/firebase_messaging/ios"
+ firebase_performance:
+ :path: ".symlinks/plugins/firebase_performance/ios"
+ Flutter:
+ :path: Flutter
+ flutter_facebook_auth:
+ :path: ".symlinks/plugins/flutter_facebook_auth/ios"
+ flutter_image_compress_common:
+ :path: ".symlinks/plugins/flutter_image_compress_common/ios"
+ flutter_inappwebview_ios:
+ :path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
+ flutter_local_notifications:
+ :path: ".symlinks/plugins/flutter_local_notifications/ios"
+ flutter_native_splash:
+ :path: ".symlinks/plugins/flutter_native_splash/ios"
+ flutter_secure_storage:
+ :path: ".symlinks/plugins/flutter_secure_storage/ios"
+ fluttertoast:
+ :path: ".symlinks/plugins/fluttertoast/ios"
+ image_picker_ios:
+ :path: ".symlinks/plugins/image_picker_ios/ios"
+ in_app_purchase_storekit:
+ :path: ".symlinks/plugins/in_app_purchase_storekit/darwin"
+ package_info_plus:
+ :path: ".symlinks/plugins/package_info_plus/ios"
+ path_provider_foundation:
+ :path: ".symlinks/plugins/path_provider_foundation/darwin"
+ permission_handler_apple:
+ :path: ".symlinks/plugins/permission_handler_apple/ios"
+ shared_preferences_foundation:
+ :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
+ sign_in_with_apple:
+ :path: ".symlinks/plugins/sign_in_with_apple/ios"
+ sqflite_darwin:
+ :path: ".symlinks/plugins/sqflite_darwin/darwin"
+ url_launcher_ios:
+ :path: ".symlinks/plugins/url_launcher_ios/ios"
+ video_player_avfoundation:
+ :path: ".symlinks/plugins/video_player_avfoundation/darwin"
+ wakelock_plus:
+ :path: ".symlinks/plugins/wakelock_plus/ios"
+ webview_flutter_wkwebview:
+ :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
+
+SPEC CHECKSUMS:
+ Adjust: 1ff981e84ae1306f8cce30e0661b3997dad1b85c
+ adjust_sdk: 38843451cc76bacb2cf583a4e8c6e4052357dde2
+ AdjustSignature: d634fc6b66295c38807f3b4e50978c1f72355950
+ advertising_id: d5de9e659986092d7ca50977dc50f4f4fcd4c30a
+ app_badge_plus: 0e3470f993dd08094e16463f57a7e0db04c6b587
+ app_links: 3dbc685f76b1693c66a6d9dd1e9ab6f73d97dc0a
+ app_tracking_transparency: 3d84f147f67ca82d3c15355c36b1fa6b66ca7c92
+ device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
+ FBAEMKit: 9900b2edd99a2d21629a6277e6166f14c6215799
+ FBSDKCoreKit: 0791f8f68a8630931a4c12aa23a56cc021551596
+ FBSDKCoreKit_Basics: 46d6b472c0dd0a5a7e972c025033d1c567f54eb4
+ FBSDKLoginKit: b4a4eba1d62eb452544411824f41689adabd5bd2
+ Firebase: 0312a2352584f782ea56f66d91606891d4607f06
+ firebase_analytics: fc59e3c0251c1baeac5ea612cfbb553ef944c6cb
+ firebase_core: 3b49a055ff54114cae400581c13671fe53936c36
+ firebase_crashlytics: 66f38fa4dd09ba785fb909ee14e97b02693162f4
+ firebase_messaging: 394589dcda43e42ec9807558a409a975e285c45b
+ firebase_performance: b6b0e7cc4567eb52a394b949547ee1fbcd28863a
+ FirebaseABTesting: d87f56707159bae64e269757a6e963d490f2eebe
+ FirebaseAnalytics: ec00fe8b93b41dc6fe4a28784b8e51da0647a248
+ FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483
+ FirebaseCoreExtension: 705ca5b14bf71d2564a0ddc677df1fc86ffa600f
+ FirebaseCoreInternal: df84dd300b561c27d5571684f389bf60b0a5c934
+ FirebaseCrashlytics: 4b96efb0ce73b38b2a85e8b8bd1bd8f63f09d015
+ FirebaseInstallations: 913cf60d0400ebd5d6b63a28b290372ab44590dd
+ FirebaseMessaging: 88950ba9485052891ebe26f6c43a52bb62248952
+ FirebasePerformance: bae7778c4448b37f2a75cb72d30c2df7d10ff227
+ FirebaseRemoteConfig: 48ef3f243742a8d72422ccfc9f986e19d7de53fd
+ FirebaseRemoteConfigInterop: 6efda51fb5e2f15b16585197e26eaa09574e8a4d
+ FirebaseSessions: dbd14adac65ce996228652c1fc3a3f576bdf3ecc
+ FirebaseSharedSwift: 20530f495084b8d840f78a100d8c5ee613375f6e
+ Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
+ flutter_facebook_auth: 2f28c889d5727b4538ed8d25be3367092b2cbef7
+ flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
+ flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
+ flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb
+ flutter_native_splash: c32d145d68aeda5502d5f543ee38c192065986cf
+ flutter_secure_storage: 1ed9476fba7e7a782b22888f956cce43e2c62f13
+ fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
+ GoogleAppMeasurement: 9abf64b682732fed36da827aa2a68f0221fd2356
+ GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a
+ GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15
+ image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
+ in_app_purchase_storekit: d1a48cb0f8b29dbf5f85f782f5dd79b21b90a5e6
+ libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
+ Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
+ nanopb: 438bc412db1928dac798aa6fd75726007be04262
+ OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
+ package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
+ path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
+ permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
+ PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
+ PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
+ SDWebImage: 9f177d83116802728e122410fb25ad88f5c7608a
+ SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380
+ shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
+ sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
+ sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
+ url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
+ video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
+ wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
+ webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2
+
+PODFILE CHECKSUM: 4305caec6b40dde0ae97be1573c53de1882a07e5
+
+COCOAPODS: 1.16.2
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..0c0d41e
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,766 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 002E1F1EA059FEE73E55E03C /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D1AEBA8280B01EA417C5A4C5 /* Pods_Runner.framework */; };
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 2F3E2165998010C253A6A3AB /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 31F0B6F62A10C414CCB11B56 /* Pods_RunnerTests.framework */; };
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
+ 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 */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 97C146E61CF9000F007C117D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 97C146ED1CF9000F007C117D;
+ remoteInfo = Runner;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 31F0B6F62A10C414CCB11B56 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 51DE980C913972D8698EADC8 /* 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 = ""; };
+ 6343944E63046AB37896D41C /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 82DA550712AB9D482426785C /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; };
+ 9696F68BF26F44CD29FBD700 /* 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 = ""; };
+ A1A3E171C7698E1D2BD5DC53 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; };
+ D1AEBA8280B01EA417C5A4C5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ FABBBF0FED9FA9D9051FC517 /* 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 = ""; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 002E1F1EA059FEE73E55E03C /* Pods_Runner.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ D04E4E00D3C0EA18445CB61B /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 2F3E2165998010C253A6A3AB /* Pods_RunnerTests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 331C8082294A63A400263BE5 /* RunnerTests */ = {
+ isa = PBXGroup;
+ children = (
+ 331C807B294A618700263BE5 /* RunnerTests.swift */,
+ );
+ path = RunnerTests;
+ 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 */,
+ 331C8082294A63A400263BE5 /* RunnerTests */,
+ B80D61B0ADE0DA08BFDD3659 /* Pods */,
+ A643DB2437D6E4CE3EFAE3C0 /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
+ );
+ 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 = "";
+ };
+ A643DB2437D6E4CE3EFAE3C0 /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ D1AEBA8280B01EA417C5A4C5 /* Pods_Runner.framework */,
+ 31F0B6F62A10C414CCB11B56 /* Pods_RunnerTests.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ B80D61B0ADE0DA08BFDD3659 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 51DE980C913972D8698EADC8 /* Pods-Runner.debug.xcconfig */,
+ 9696F68BF26F44CD29FBD700 /* Pods-Runner.release.xcconfig */,
+ FABBBF0FED9FA9D9051FC517 /* Pods-Runner.profile.xcconfig */,
+ 6343944E63046AB37896D41C /* Pods-RunnerTests.debug.xcconfig */,
+ 82DA550712AB9D482426785C /* Pods-RunnerTests.release.xcconfig */,
+ A1A3E171C7698E1D2BD5DC53 /* Pods-RunnerTests.profile.xcconfig */,
+ );
+ path = Pods;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 331C8080294A63A400263BE5 /* RunnerTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
+ buildPhases = (
+ 5EB24FE879832BF5F888D5D5 /* [CP] Check Pods Manifest.lock */,
+ 331C807D294A63A400263BE5 /* Sources */,
+ 331C807F294A63A400263BE5 /* Resources */,
+ D04E4E00D3C0EA18445CB61B /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */,
+ );
+ name = RunnerTests;
+ productName = RunnerTests;
+ productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ EFBE2EF9E47855D24F005B50 /* [CP] Check Pods Manifest.lock */,
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ 9D34C6E5552B9F95B0AA53FB /* [CP] Embed Pods Frameworks */,
+ F935970CD591A26D89CA2F46 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1510;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 331C8080294A63A400263BE5 = {
+ CreatedOnToolsVersion = 14.0;
+ TestTargetID = 97C146ED1CF9000F007C117D;
+ };
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ 331C8080294A63A400263BE5 /* RunnerTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 331C807F294A63A400263BE5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ };
+ 5EB24FE879832BF5F888D5D5 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+ 9D34C6E5552B9F95B0AA53FB /* [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;
+ };
+ EFBE2EF9E47855D24F005B50 /* [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;
+ };
+ F935970CD591A26D89CA2F46 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Copy Pods Resources";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 331C807D294A63A400263BE5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 97C146ED1CF9000F007C117D /* Runner */;
+ targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 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;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ DEVELOPMENT_TEAM = 38X8FL2527;
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.kinetra.adehok.app.flutterKinetra;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 1;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 331C8088294A63A400263BE5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 6343944E63046AB37896D41C /* Pods-RunnerTests.debug.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.kinetra.adehok.app.flutterKinetra.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Debug;
+ };
+ 331C8089294A63A400263BE5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 82DA550712AB9D482426785C /* Pods-RunnerTests.release.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.kinetra.adehok.app.flutterKinetra.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Release;
+ };
+ 331C808A294A63A400263BE5 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = A1A3E171C7698E1D2BD5DC53 /* Pods-RunnerTests.profile.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.kinetra.adehok.app.flutterKinetra.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 12.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ DEVELOPMENT_TEAM = 38X8FL2527;
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.kinetra.adehok.app.flutterKinetra;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 1;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES;
+ CLANG_ENABLE_MODULES = YES;
+ CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
+ DEVELOPMENT_TEAM = 38X8FL2527;
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = com.kinetra.adehok.app.flutterKinetra;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
+ SUPPORTS_MACCATALYST = NO;
+ SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 1;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 331C8088294A63A400263BE5 /* Debug */,
+ 331C8089294A63A400263BE5 /* Release */,
+ 331C808A294A63A400263BE5 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100755
index 0000000..919434a
--- /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 100755
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 100755
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..e3773d4
--- /dev/null
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100755
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 100755
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 100755
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 100755
index 0000000..6266644
--- /dev/null
+++ b/ios/Runner/AppDelegate.swift
@@ -0,0 +1,13 @@
+import Flutter
+import UIKit
+
+@main
+@objc class AppDelegate: FlutterAppDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ GeneratedPluginRegistrant.register(with: self)
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100755
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 100755
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 100755
index 0000000..7353c41
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 100755
index 0000000..797d452
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 100755
index 0000000..6ed2d93
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 100755
index 0000000..4cd7b00
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 100755
index 0000000..fe73094
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 100755
index 0000000..321773c
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 100755
index 0000000..797d452
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 100755
index 0000000..502f463
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 100755
index 0000000..0ec3034
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 100755
index 0000000..0ec3034
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 100755
index 0000000..e9f5fea
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 100755
index 0000000..84ac32a
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 100755
index 0000000..8953cba
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 100755
index 0000000..0467bf1
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 100755
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 100755
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 100755
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 100755
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 100755
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 100755
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 100755
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..caae079
--- /dev/null
+++ b/ios/Runner/Info.plist
@@ -0,0 +1,47 @@
+
+
+
+
+ CADisableMinimumFrameDurationOnPhone
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ Flutter Kinetra
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ flutter_kinetra
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ UIApplicationSupportsIndirectInputEvents
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+
+
+
diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h
new file mode 100755
index 0000000..308a2a5
--- /dev/null
+++ b/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift
new file mode 100644
index 0000000..86a7c3b
--- /dev/null
+++ b/ios/RunnerTests/RunnerTests.swift
@@ -0,0 +1,12 @@
+import Flutter
+import UIKit
+import XCTest
+
+class RunnerTests: XCTestCase {
+
+ func testExample() {
+ // If you add code to the Runner application, consider adding tests here.
+ // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
+ }
+
+}
diff --git a/lib/dio_cilent/kt_apis.dart b/lib/dio_cilent/kt_apis.dart
new file mode 100644
index 0000000..084d255
--- /dev/null
+++ b/lib/dio_cilent/kt_apis.dart
@@ -0,0 +1,99 @@
+class KtApis {
+ static const String baseUrl = "https://test1-api.guyantv.com";
+ // static const String baseUrl = "https://api-pdaroll.pdaroll.com/panda";
+
+ static const String homeAllModules = "/home/all-modules";
+ static const String newShortPlay = "/newShortPlay";
+ static const String homeVideoList = "/videoList";
+ static const String getCategories = "/getCategories";
+ static const String getMostSearch = "/search/hots";
+ static const String search = "/search";
+ static const String getVideoDetails = "/getVideoDetails";
+ static const String getRecommands = "/getRecommands";
+ static const String getMyHistoryList = "/myHistorys";
+ static const String getMyCollections = "/myCollections";
+ static const String collectVideo = "/collect";
+ static const String cancelCollectVideo = "/cancelCollect";
+ static const String getDetailsRecommand = "/getDetailsRecommand";
+ static const String getRevolutions = "/getRevolutions";
+
+ // 播放上报
+ static const String uploadHistorySeconds = "/uploadHistorySeconds";
+ static const String createHistory = "/createHistory";
+ static const String uploadW2a = "/w2aSelfAttribution";
+ static const String activeAfterWatchingVideo = "/activeAfterWatchingVideo";
+ static String W2A_PREFIX = "[QJ]";
+ static String W2A_NAME = "pandaloom";
+ static String adjustToken = "z44550428xz4";
+
+ // 用户
+ static const String signOut = "/customer/signout";
+ static const String logOff = "/customer/logoff";
+ static const String login = "/customer/login";
+ static const String getCustomerInfo = "/customer/info";
+ static const String register = "/customer/register";
+ static const String uploadNoticeStatus = "/customer/uploadNoticeStatus";
+ static const String onLine = "/customer/onLine"; //在线用户统计(10分钟1次)
+ static const String enterTheApp = "/customer/enterTheApp";
+ static const String leaveApp = "/customer/leaveApp";
+ static const String getNoticeNum = "/noticeNum";
+ static const String sendMessageReport = "/message/sendReport";
+ static const String reportFirebaseToken = "/customer/firebaseToken";
+ static const String reportEvent = "/event/add";
+
+ // 商品和购买
+ static const String paySettingsV3 = "/paySettingsV3";
+ static const String paySettingsV4 = "/paySettingsV4";
+ static const String getVipPaySetting = "/getVipPaySetting";
+ static const String createOrder = "/createOrder";
+ static const String createApplePay = "/applePaid";
+ static const String createGooglePay = "/googlePaid";
+ static const String buyVideo = "/buy_video";
+ static const String openNotify = "/openNotify";
+
+ ///钱包
+ static const String getCustomerOrder = "/getCustomerOrder";
+ static const String getCustomerBuyRecords = "/getCustomerBuyRecords";
+ static const String getSendCoinList = "/sendCoinList";
+
+ ///官网
+ static String WEB_SITE_INDEX = "https://www.csjiuxi.com/";
+
+ ///隐私
+ static String WEB_SITE_PRIVATE = "${WEB_SITE_INDEX}private";
+
+ ///用户
+ static String WEB_SITE_POLICY = "${WEB_SITE_INDEX}user_policy";
+
+ ///儿童个人信息保护规则
+ static String WEB_SITE_INFO_PROTECT =
+ "${WEB_SITE_INDEX}information_protection";
+
+ ///第三方共享清单
+ static String WEB_SITE_INFO_SHARE = "${WEB_SITE_INDEX}information_sharing";
+
+ ///收集个人信息明示清单
+ static String WEB_SITE_PERSONAL_INFO_DISCLOSURE =
+ "${WEB_SITE_INDEX}persoInfor_disclosure";
+
+ ///青少年互联网文明公约
+ static String WEB_SITE_CIVIZ = "${WEB_SITE_INDEX}civizatio_convention";
+
+ static String WEB_SITE_HOST = "https://campaign.pdaroll.com/";
+ static String WEB_SITE_ACTIVITY = "${WEB_SITE_HOST}pages/reward/theme3";
+
+ ///反馈首页
+ static String WEB_SITE_FEEDBACK = "${WEB_SITE_HOST}pages/leave/index";
+
+ ///反馈列表
+ static String WEB_SITE_FEEDBACK_LIST = "${WEB_SITE_HOST}pages/leave/list";
+
+ ///反馈详情
+ static String WEB_SITE_FEEDBACK_DETAIL = "${WEB_SITE_HOST}pages/leave/detail";
+
+ ///钱包
+ static String WEB_SITE_WALLET = "${WEB_SITE_HOST}pages/leave/detail";
+
+ /// w2a
+ static String WEB_2_APP_INDEX = "https://w2a.pdaroll.com/";
+}
diff --git a/lib/dio_cilent/kt_request.dart b/lib/dio_cilent/kt_request.dart
new file mode 100644
index 0000000..0c8d9d2
--- /dev/null
+++ b/lib/dio_cilent/kt_request.dart
@@ -0,0 +1,338 @@
+import 'package:dio/dio.dart';
+import 'package:flustars/flustars.dart';
+import 'package:flutter/foundation.dart';
+import 'package:get/get.dart' hide Response;
+import 'package:pretty_dio_logger/pretty_dio_logger.dart';
+
+import '../kt_pages/kt_routes.dart';
+import '../kt_utils/kt_keys.dart';
+import '../kt_utils/kt_toast_utils.dart';
+import '../kt_utils/kt_user_utils.dart';
+import 'kt_apis.dart';
+import 'kt_request_interceptor.dart';
+
+/// HTTP请求配置类
+class HttpConfig {
+ static const String baseUrl = KtApis.baseUrl;
+ static const int connectTimeout = 5000; // 连接超时时间(ms)
+ static const int receiveTimeout = 15000; // 接收超时时间(ms)
+ static const int sendTimeout = 5000; // 发送超时时间(ms)
+}
+
+/// API响应结果类
+class ApiResponse {
+ final bool success;
+ final T? data;
+ final String? message;
+ final int? code;
+
+ ApiResponse({required this.success, this.data, this.message, this.code});
+
+ factory ApiResponse.fromJson(Map json) {
+ return ApiResponse(
+ success: json['success'] ?? false,
+ data: json['data'],
+ message: json['msg'],
+ code: json['code'],
+ );
+ }
+
+ Map toJson() {
+ return {'success': success, 'data': data, 'message': message, 'code': code};
+ }
+}
+
+/// HTTP请求方法枚举
+enum HttpMethod { get, post, put, delete, patch }
+
+/// 统一的API异常类
+class ApiException implements Exception {
+ final int? code;
+ final String message;
+ final dynamic error;
+
+ ApiException({this.code, required this.message, this.error});
+
+ @override
+ String toString() {
+ return 'ApiException{code: $code, message: $message, error: $error}';
+ }
+}
+
+/// Dio请求封装类
+class HttpClient {
+ static final HttpClient _instance = HttpClient._internal();
+
+ factory HttpClient() => _instance;
+ late Dio _dio;
+
+ HttpClient._internal() {
+ _initDio();
+ }
+
+ void _initDio() {
+ BaseOptions options = BaseOptions(
+ baseUrl: HttpConfig.baseUrl,
+ connectTimeout: Duration(seconds: HttpConfig.connectTimeout),
+ receiveTimeout: Duration(seconds: HttpConfig.receiveTimeout),
+ sendTimeout: Duration(seconds: HttpConfig.sendTimeout),
+ responseType: ResponseType.json,
+ );
+
+ _dio = Dio(options);
+
+ _dio.interceptors.add(RequestInterceptor());
+ // 添加拦截器
+ _dio.interceptors.add(
+ InterceptorsWrapper(
+ onRequest: (options, handler) {
+ return handler.next(options);
+ },
+ onResponse: (response, handler) {
+ return handler.next(response);
+ },
+ onError: (DioException e, handler) {
+ if (kDebugMode) {
+ print('请求错误: ${e.message}');
+ if (e.response != null) {
+ print('错误响应: ${e.response!.data}');
+ }
+ }
+ return handler.next(_handleError(e));
+ },
+ ),
+ );
+ _dio.interceptors.add(
+ PrettyDioLogger(requestBody: true, requestHeader: true),
+ );
+ }
+
+ /// 处理Dio错误
+ DioException _handleError(DioException e) {
+ switch (e.type) {
+ case DioExceptionType.connectionTimeout:
+ return DioException(
+ requestOptions: e.requestOptions,
+ error: ApiException(code: -1, message: 'Connection timeout'),
+ );
+ case DioExceptionType.sendTimeout:
+ return DioException(
+ requestOptions: e.requestOptions,
+ error: ApiException(code: -2, message: 'Connection timeout'),
+ );
+ case DioExceptionType.receiveTimeout:
+ return DioException(
+ requestOptions: e.requestOptions,
+ error: ApiException(code: -3, message: 'Connection timeout'),
+ );
+ case DioExceptionType.badResponse:
+ final int? statusCode = e.response?.statusCode;
+ String message = 'Connection failed';
+
+ if (statusCode != null) {
+ switch (statusCode) {
+ case 400:
+ message = '请求参数错误';
+ break;
+ case 401:
+ message = 'Token已过期';
+ SpUtil.remove(KtKeys.token);
+ clearAuthToken();
+ Get.offAllNamed(KtRoutes.splash);
+ break;
+ case 402:
+ message = '未授权,请先登录';
+ // ToastUtils.show(
+ // 'Please log out of the account on other devices in time, otherwise the App on other devices will be unavailable.',
+ // );
+ KtUserUtil().register(toHome: false);
+
+ // SpUtil.remove(SpKeys.token);
+ // clearAuthToken();
+ // Get.offAllNamed(AppRoutes.splash);
+ break;
+ case 403:
+ message = '禁止访问,权限不足';
+ break;
+ case 404:
+ message = '请求资源不存在';
+ break;
+ case 500:
+ message = '服务器内部错误';
+ break;
+ case 502:
+ message = '网关错误';
+ break;
+ case 503:
+ message = '服务不可用';
+ break;
+ case 504:
+ message = '网关超时';
+ break;
+ }
+ }
+
+ return DioException(
+ requestOptions: e.requestOptions,
+ error: ApiException(
+ code: statusCode ?? -4,
+ message: message,
+ error: e.response?.data,
+ ),
+ );
+ case DioExceptionType.cancel:
+ return DioException(
+ requestOptions: e.requestOptions,
+ error: ApiException(code: -5, message: '请求已取消'),
+ );
+ case DioExceptionType.unknown:
+ return DioException(
+ requestOptions: e.requestOptions,
+ error: ApiException(code: -6, message: '未知错误,请稍后再试', error: e.error),
+ );
+ default:
+ return e;
+ }
+ }
+
+ /// 统一的请求方法
+ Future> request(
+ String path, {
+ HttpMethod method = HttpMethod.post,
+ dynamic data,
+ Map? queryParameters,
+ Options? options,
+ ProgressCallback? onSendProgress,
+ ProgressCallback? onReceiveProgress,
+ T Function(dynamic data)? parser,
+ bool showErrorToast = false,
+ }) async {
+ try {
+ Options requestOptions = options ?? Options();
+ requestOptions.method = method.name.toUpperCase();
+
+ Response response;
+
+ switch (method) {
+ case HttpMethod.get:
+ response = await _dio.get(
+ path,
+ queryParameters: queryParameters,
+ options: requestOptions,
+ onReceiveProgress: onReceiveProgress,
+ );
+ break;
+ case HttpMethod.post:
+ response = await _dio.post(
+ path,
+ data: data,
+ queryParameters: queryParameters,
+ options: requestOptions,
+ onSendProgress: onSendProgress,
+ onReceiveProgress: onReceiveProgress,
+ );
+ break;
+ case HttpMethod.put:
+ response = await _dio.put(
+ path,
+ data: data,
+ queryParameters: queryParameters,
+ options: requestOptions,
+ );
+ break;
+ case HttpMethod.delete:
+ response = await _dio.delete(
+ path,
+ data: data,
+ queryParameters: queryParameters,
+ options: requestOptions,
+ );
+ break;
+ case HttpMethod.patch:
+ response = await _dio.patch(
+ path,
+ data: data,
+ queryParameters: queryParameters,
+ options: requestOptions,
+ );
+ break;
+ }
+
+ // 解析响应数据
+ if (response.statusCode == 200) {
+ final responseData = response.data;
+
+ if (responseData['code'] == 200) {
+ // 如果有自定义解析器,使用解析器处理数据
+ if (parser != null) {
+ return ApiResponse(success: true, data: parser(responseData));
+ }
+
+ // 默认解析
+ if (responseData is Map) {
+ responseData.putIfAbsent('success', () => true);
+ return ApiResponse.fromJson(responseData);
+ } else {
+ return ApiResponse(success: true, data: responseData as T?);
+ }
+ } else {
+ if (showErrorToast)
+ KtToastUtils.showSuccess(placeholder: responseData['msg']);
+ return ApiResponse(
+ success: false,
+ message: responseData['msg'],
+ data: responseData as T?,
+ );
+ }
+ } else {
+ throw ApiException(
+ code: response.statusCode,
+ message: '请求失败,状态码: ${response.statusCode}',
+ error: response.data,
+ );
+ }
+ } catch (e) {
+ if (e is ApiException) {
+ rethrow;
+ } else {
+ throw ApiException(code: -1000, message: '请求发生异常: $e', error: e);
+ }
+ }
+ }
+
+ /// 设置认证令牌
+ void setAuthToken(String token) {
+ _dio.options.headers['Authorization'] = token;
+ // _dio.options.headers['Authorization'] = 'Bearer $token';
+ }
+
+ /// 清除认证令牌
+ void clearAuthToken() {
+ _dio.options.headers.remove('Authorization');
+ }
+
+ /// 添加自定义请求头字段
+ void addHeader(String key, String value) {
+ _dio.options.headers[key] = value;
+ }
+
+ /// 批量添加自定义请求头字段
+ void addHeaders(Map headers) {
+ headers.forEach((key, value) => _dio.options.headers[key] = value);
+ }
+
+ /// 移除指定请求头字段
+ void removeHeader(String key) {
+ _dio.options.headers.remove(key);
+ }
+
+ /// 清除所有自定义请求头字段
+ void clearHeaders() {
+ // 保留基础的Content-Type
+ final contentType = _dio.options.headers['Content-Type'];
+ _dio.options.headers.clear();
+ if (contentType != null) {
+ _dio.options.headers['Content-Type'] = contentType;
+ }
+ }
+}
diff --git a/lib/dio_cilent/kt_request_interceptor.dart b/lib/dio_cilent/kt_request_interceptor.dart
new file mode 100644
index 0000000..c85c8a9
--- /dev/null
+++ b/lib/dio_cilent/kt_request_interceptor.dart
@@ -0,0 +1,45 @@
+import 'dart:io';
+
+import 'package:dio/dio.dart';
+import 'package:flutter_kinetra/kt_utils/kt_utils.dart';
+import 'package:flustars/flustars.dart';
+
+import '../kt_utils/kt_device_info_utils.dart';
+import '../kt_utils/kt_keys.dart';
+
+class RequestInterceptor extends Interceptor {
+ @override
+ void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
+ // 不加密
+ // bool isRelease = kReleaseMode;
+ // if (!isRelease) {
+ // options.headers.addAll({'security': false});
+ // }
+ final deviceInfo = KtDeviceInfoUtil();
+ String token = SpUtil.getString(KtKeys.token) ?? '';
+ if (token.isNotEmpty) {
+ options.headers.addAll({'Authorization': token});
+ }
+ String idfa = SpUtil.getString(KtKeys.iosIDFA) ?? '';
+ String gaid = Platform.isIOS
+ ? (deviceInfo.deviceIdfv ?? '')
+ : SpUtil.getString(KtKeys.googleAid) ?? '';
+ options.headers.addAll({
+ 'security': false,
+ 'lang-key': 'en',
+ 'device-id': deviceInfo.deviceId ?? 'unknown',
+ 'system-type': deviceInfo.systemType ?? 'unknown',
+ 'model': deviceInfo.deviceModel ?? 'unknown',
+ 'system-version': deviceInfo.osVersion ?? 'unknown',
+ 'brand': deviceInfo.deviceBrand ?? 'unknown',
+ 'app-version': deviceInfo.appVersion ?? 'unknown',
+ 'app-name': 'PandaLoom',
+ "time-zone": KtUtils.getTimeZoneOffset(DateTime.now()),
+ 'idfa': idfa,
+ 'idfv': deviceInfo.deviceIdfv,
+ "device-gaid": gaid,
+ });
+
+ super.onRequest(options, handler);
+ }
+}
diff --git a/lib/kt_model/kt_register_bean.dart b/lib/kt_model/kt_register_bean.dart
new file mode 100644
index 0000000..cbb177d
--- /dev/null
+++ b/lib/kt_model/kt_register_bean.dart
@@ -0,0 +1,48 @@
+import 'dart:convert';
+
+/// token : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJjdXN0b21lcl9pZCI6NzI4NjIsImlzX3RvdXJpc3QiOnRydWUsImV4cGlyZV90aW1lIjoxNzUxNTExODYxfQ.ujSafDOgS2hYBWD2rpaQ_KhEdaTAmjRdwn7iZyALAqE"
+/// customer_id : 72862
+/// auto_login : false
+
+KtRegisterBean ktRegisterBeanFromJson(String str) =>
+ KtRegisterBean.fromJson(json.decode(str));
+String ktRegisterBeanToJson(KtRegisterBean data) => json.encode(data.toJson());
+
+class KtRegisterBean {
+ KtRegisterBean({String? token, num? customerId, bool? autoLogin}) {
+ _token = token;
+ _customerId = customerId;
+ _autoLogin = autoLogin;
+ }
+
+ KtRegisterBean.fromJson(dynamic json) {
+ _token = json['token'];
+ _customerId = json['customer_id'];
+ _autoLogin = json['auto_login'];
+ }
+
+ String? _token;
+ num? _customerId;
+ bool? _autoLogin;
+
+ KtRegisterBean copyWith({String? token, num? customerId, bool? autoLogin}) =>
+ KtRegisterBean(
+ token: token ?? _token,
+ customerId: customerId ?? _customerId,
+ autoLogin: autoLogin ?? _autoLogin,
+ );
+
+ String? get token => _token;
+
+ num? get customerId => _customerId;
+
+ bool? get autoLogin => _autoLogin;
+
+ Map toJson() {
+ final map = {};
+ map['token'] = _token;
+ map['customer_id'] = _customerId;
+ map['auto_login'] = _autoLogin;
+ return map;
+ }
+}
diff --git a/lib/kt_model/kt_short_video_bean.dart b/lib/kt_model/kt_short_video_bean.dart
new file mode 100644
index 0000000..c3a13f2
--- /dev/null
+++ b/lib/kt_model/kt_short_video_bean.dart
@@ -0,0 +1,555 @@
+import 'dart:convert';
+
+/// id : 378
+/// short_id : 150
+/// short_play_id : 378
+/// name : "Contractual Couple"
+/// description : "Shen Yuchu is Li Qian's superior. The two people who wouldn't have had any intersection originally were connected because of an unexpected one-night stand. What's more dramatic is that the ring representing the fate and predestination of the Shen family was accidentally worn on Li Qian's hand. After a series of events, Li Qian and Shen Yuchu signed a marriage agreement to be a couple in name only. But later, the appearance of the badge exposed a past event from their youth - Li Qian turned out to be the savior Shen Yuchu had been looking for all along. Can Shen Yuchu, who has already broken Li Qian's heart, win her heart back now? "
+/// process : 1
+/// image_url : "https://static3.guyantv.com/eyJrZXkiOiJpbWFnZS83MDM3MGY2OWEyMzk5MzIwMjkwNi5qcGciLCJlZGl0cyI6eyJyZXNpemUiOnsiZml0IjoiY292ZXIiLCJ3aWR0aCI6MjIwfX19?sign=$1fea5d55dfbb3e2dacc00f8176af642021904100edcd3817c226ab211418d7a1e46b75ef14919a2207c044532067a7ae3f"
+/// horizontally_img : ""
+/// buy_type : 1
+/// tag_type : ""
+/// all_coins : 0
+/// collect_total : 50
+/// watch_total : 7487
+/// episode_total : 36
+/// search_click_total : 7081
+/// video_url : "https://static3.guyantv.com/videom3u8/389609ccb06761c46544/389609ccb06761c46544.m3u8"
+/// category : ["Sadomasochism"]
+/// video_info : {"id":19136,"short_play_video_id":19136,"short_play_id":207,"short_id":133,"promise_view_ad":0,"video_url":"https://static.wanmwl.com/videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8","coins":0,"vip_coins":0,"episode":1,"is_vip":2,"revolution":{"r540":"videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8","r720":"videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8","r1080":"videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8"},"image_url":"https://static.wanmwl.com/eyJrZXkiOiJpbWFnZS9iY2U2NTkyNDUwN2FmZDQyOTdkZC5qcGciLCJlZGl0cyI6eyJyZXNpemUiOnsiZml0IjoiY292ZXIifH19?sign=$13136e4e95c2a9c82971428cbd1d4f533b403890bb5a7c390b1d05a55588390cb27c74948f"}
+/// is_collect : false
+/// categoryList : [{"id":1,"name":""}]
+
+KtShortVideoBean ktShortVideoBeanFromJson(String str) =>
+ KtShortVideoBean.fromJson(json.decode(str));
+
+String ktShortVideoBeanToJson(KtShortVideoBean data) =>
+ json.encode(data.toJson());
+
+class KtShortVideoBean {
+ KtShortVideoBean({
+ num? id,
+ num? shortId,
+ num? shortPlayId,
+ String? name,
+ String? description,
+ num? process,
+ num? playTime,
+ String? imageUrl,
+ String? horizontallyImg,
+ num? buyType,
+ String? tagType,
+ num? allCoins,
+ num? collectTotal,
+ num? watchTotal,
+ num? episodeTotal,
+ num? searchClickTotal,
+ String? videoUrl,
+ List? category,
+ VideoInfo? videoInfo,
+ bool? isCollect,
+ List? categoryList,
+ }) {
+ _id = id;
+ _shortId = shortId;
+ _shortPlayId = shortPlayId;
+ _name = name;
+ _description = description;
+ _process = process;
+ _playTime = playTime;
+ _imageUrl = imageUrl;
+ _horizontallyImg = horizontallyImg;
+ _buyType = buyType;
+ _tagType = tagType;
+ _allCoins = allCoins;
+ _collectTotal = collectTotal;
+ _watchTotal = watchTotal;
+ _episodeTotal = episodeTotal;
+ _searchClickTotal = searchClickTotal;
+ _videoUrl = videoUrl;
+ _category = category;
+ _videoInfo = videoInfo;
+ _isCollect = isCollect;
+ _categoryList = categoryList;
+ }
+
+ KtShortVideoBean.fromJson(dynamic json) {
+ _id = json['id'];
+ _shortId = json['short_id'];
+ _shortPlayId = json['short_play_id'];
+ _name = json['name'];
+ _description = json['description'];
+ _process = json['process'];
+ _playTime = json['playTime'];
+ _imageUrl = json['image_url'];
+ _horizontallyImg = json['horizontally_img'];
+ _buyType = json['buy_type'];
+ _tagType = json['tag_type'];
+ _allCoins = json['all_coins'];
+ _collectTotal = json['collect_total'];
+ _watchTotal = json['watch_total'];
+ _episodeTotal = json['episode_total'];
+ _searchClickTotal = json['search_click_total'];
+ _videoUrl = json['video_url'];
+ _category = json['category'] != null ? json['category'].cast() : [];
+ _videoInfo = json['video_info'] != null
+ ? VideoInfo.fromJson(json['video_info'])
+ : null;
+ _isCollect = json['is_collect'];
+ if (json['categoryList'] != null) {
+ _categoryList = [];
+ json['categoryList'].forEach((v) {
+ _categoryList?.add(Category.fromJson(v));
+ });
+ }
+ }
+
+ num? _id;
+ num? _shortId;
+ num? _shortPlayId;
+ String? _name;
+ String? _description;
+ num? _process;
+ num? _playTime;
+ String? _imageUrl;
+ String? _horizontallyImg;
+ num? _buyType;
+ String? _tagType;
+ num? _allCoins;
+ num? _collectTotal;
+ num? _watchTotal;
+ num? _episodeTotal;
+ num? _searchClickTotal;
+ String? _videoUrl;
+ List? _category;
+ VideoInfo? _videoInfo;
+ bool? _isCollect;
+ List? _categoryList;
+
+ KtShortVideoBean copyWith({
+ num? id,
+ num? shortId,
+ num? shortPlayId,
+ String? name,
+ String? description,
+ num? process,
+ num? playTime,
+ String? imageUrl,
+ String? horizontallyImg,
+ num? buyType,
+ String? tagType,
+ num? allCoins,
+ num? collectTotal,
+ num? watchTotal,
+ num? episodeTotal,
+ num? searchClickTotal,
+ String? videoUrl,
+ List? category,
+ VideoInfo? videoInfo,
+ bool? isCollect,
+ List? categoryList,
+ }) => KtShortVideoBean(
+ id: id ?? _id,
+ shortId: shortId ?? _shortId,
+ shortPlayId: shortPlayId ?? _shortPlayId,
+ name: name ?? _name,
+ description: description ?? _description,
+ process: process ?? _process,
+ playTime: playTime ?? _playTime,
+ imageUrl: imageUrl ?? _imageUrl,
+ horizontallyImg: horizontallyImg ?? _horizontallyImg,
+ buyType: buyType ?? _buyType,
+ tagType: tagType ?? _tagType,
+ allCoins: allCoins ?? _allCoins,
+ collectTotal: collectTotal ?? _collectTotal,
+ watchTotal: watchTotal ?? _watchTotal,
+ episodeTotal: episodeTotal ?? _episodeTotal,
+ searchClickTotal: searchClickTotal ?? _searchClickTotal,
+ videoUrl: videoUrl ?? _videoUrl,
+ category: category ?? _category,
+ videoInfo: videoInfo ?? _videoInfo,
+ isCollect: isCollect ?? _isCollect,
+ categoryList: categoryList ?? _categoryList,
+ );
+
+ num? get id => _id;
+
+ num? get shortId => _shortId;
+
+ num? get shortPlayId => _shortPlayId;
+
+ String? get name => _name;
+
+ String? get description => _description;
+
+ num? get process => _process;
+
+ num? get playTime => _playTime;
+
+ String? get imageUrl => _imageUrl;
+
+ String? get horizontallyImg => _horizontallyImg;
+
+ num? get buyType => _buyType;
+
+ String? get tagType => _tagType;
+
+ num? get allCoins => _allCoins;
+
+ num? get collectTotal => _collectTotal;
+
+ num? get watchTotal => _watchTotal;
+
+ num? get episodeTotal => _episodeTotal;
+
+ num? get searchClickTotal => _searchClickTotal;
+
+ String? get videoUrl => _videoUrl;
+
+ List? get category => _category;
+
+ VideoInfo? get videoInfo => _videoInfo;
+
+ bool? get isCollect => _isCollect;
+
+ List? get categoryList => _categoryList;
+
+ set id(num? value) => _id = value;
+
+ set shortId(num? value) => _shortId = value;
+
+ set shortPlayId(num? value) => _shortPlayId = value;
+
+ set name(String? value) => _name = value;
+
+ set description(String? value) => _description = value;
+
+ set process(num? value) => _process = value;
+
+ set playTime(num? value) => _playTime = value;
+
+ set imageUrl(String? value) => _imageUrl = value;
+
+ set horizontallyImg(String? value) => _horizontallyImg = value;
+
+ set buyType(num? value) => _buyType = value;
+
+ set tagType(String? value) => _tagType = value;
+
+ set allCoins(num? value) => _allCoins = value;
+
+ set collectTotal(num? value) => _collectTotal = value;
+
+ set watchTotal(num? value) => _watchTotal = value;
+
+ set episodeTotal(num? value) => _episodeTotal = value;
+
+ set searchClickTotal(num? value) => _searchClickTotal = value;
+
+ set videoUrl(String? value) => _videoUrl = value;
+
+ set category(List? value) => _category = value;
+
+ set videoInfo(VideoInfo? value) => _videoInfo = value;
+
+ set isCollect(bool? value) => _isCollect = value;
+
+ set categoryList(List? value) => _categoryList = value;
+
+ Map toJson() {
+ final map = {};
+ map['id'] = _id;
+ map['short_id'] = _shortId;
+ map['short_play_id'] = _shortPlayId;
+ map['name'] = _name;
+ map['description'] = _description;
+ map['process'] = _process;
+ map['playTime'] = _playTime;
+ map['image_url'] = _imageUrl;
+ map['horizontally_img'] = _horizontallyImg;
+ map['buy_type'] = _buyType;
+ map['tag_type'] = _tagType;
+ map['all_coins'] = _allCoins;
+ map['collect_total'] = _collectTotal;
+ map['watch_total'] = _watchTotal;
+ map['episode_total'] = _episodeTotal;
+ map['search_click_total'] = _searchClickTotal;
+ map['video_url'] = _videoUrl;
+ map['category'] = _category;
+ if (_videoInfo != null) {
+ map['video_info'] = _videoInfo?.toJson();
+ }
+ map['is_collect'] = _isCollect;
+ if (_categoryList != null) {
+ map['categoryList'] = _categoryList?.map((v) => v.toJson()).toList();
+ }
+ return map;
+ }
+}
+
+/// id : 1
+/// name : ""
+
+Category categoryFromJson(String str) => Category.fromJson(json.decode(str));
+
+String categoryToJson(Category data) => json.encode(data.toJson());
+
+class Category {
+ Category({num? id, String? name}) {
+ _id = id;
+ _name = name;
+ }
+
+ Category.fromJson(dynamic json) {
+ _id = json['id'];
+ _name = json['name'];
+ }
+
+ num? _id;
+ String? _name;
+
+ Category copyWith({num? id, String? name}) =>
+ Category(id: id ?? _id, name: name ?? _name);
+
+ num? get id => _id;
+
+ String? get name => _name;
+
+ set id(num? value) => _id = value;
+
+ set name(String? value) => _name = value;
+
+ Map toJson() {
+ final map = {};
+ map['id'] = _id;
+ map['name'] = _name;
+ return map;
+ }
+}
+
+/// id : 19136
+/// short_play_video_id : 19136
+/// short_play_id : 207
+/// short_id : 133
+/// promise_view_ad : 0
+/// video_url : "https://static.wanmwl.com/videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8"
+/// coins : 0
+/// vip_coins : 0
+/// episode : 1
+/// is_vip : 2
+/// revolution : {"r540":"videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8","r720":"videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8","r1080":"videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8"}
+/// image_url : "https://static.wanmwl.com/eyJrZXkiOiJpbWFnZS9iY2U2NTkyNDUwN2FmZDQyOTdkZC5qcGciLCJlZGl0cyI6eyJyZXNpemUiOnsiZml0IjoiY292ZXIifH19?sign=$13136e4e95c2a9c82971428cbd1d4f533b403890bb5a7c390b1d05a55588390cb27c74948f"
+
+VideoInfo videoInfoFromJson(String str) => VideoInfo.fromJson(json.decode(str));
+
+String videoInfoToJson(VideoInfo data) => json.encode(data.toJson());
+
+class VideoInfo {
+ VideoInfo({
+ num? id,
+ num? shortPlayVideoId,
+ num? shortPlayId,
+ num? shortId,
+ num? promiseViewAd,
+ String? videoUrl,
+ num? coins,
+ num? vipCoins,
+ num? episode,
+ num? isVip,
+ Revolution? revolution,
+ String? imageUrl,
+ }) {
+ _id = id;
+ _shortPlayVideoId = shortPlayVideoId;
+ _shortPlayId = shortPlayId;
+ _shortId = shortId;
+ _promiseViewAd = promiseViewAd;
+ _videoUrl = videoUrl;
+ _coins = coins;
+ _vipCoins = vipCoins;
+ _episode = episode;
+ _isVip = isVip;
+ _revolution = revolution;
+ _imageUrl = imageUrl;
+ }
+
+ VideoInfo.fromJson(dynamic json) {
+ _id = json['id'];
+ _shortPlayVideoId = json['short_play_video_id'];
+ _shortPlayId = json['short_play_id'];
+ _shortId = json['short_id'];
+ _promiseViewAd = json['promise_view_ad'];
+ _videoUrl = json['video_url'];
+ _coins = json['coins'];
+ _vipCoins = json['vip_coins'];
+ _episode = json['episode'];
+ _isVip = json['is_vip'];
+ _revolution = json['revolution'] != null
+ ? Revolution.fromJson(json['revolution'])
+ : null;
+ _imageUrl = json['image_url'];
+ }
+
+ num? _id;
+ num? _shortPlayVideoId;
+ num? _shortPlayId;
+ num? _shortId;
+ num? _promiseViewAd;
+ String? _videoUrl;
+ num? _coins;
+ num? _vipCoins;
+ num? _episode;
+ num? _isVip;
+ Revolution? _revolution;
+ String? _imageUrl;
+
+ VideoInfo copyWith({
+ num? id,
+ num? shortPlayVideoId,
+ num? shortPlayId,
+ num? shortId,
+ num? promiseViewAd,
+ String? videoUrl,
+ num? coins,
+ num? vipCoins,
+ num? episode,
+ num? isVip,
+ Revolution? revolution,
+ String? imageUrl,
+ }) => VideoInfo(
+ id: id ?? _id,
+ shortPlayVideoId: shortPlayVideoId ?? _shortPlayVideoId,
+ shortPlayId: shortPlayId ?? _shortPlayId,
+ shortId: shortId ?? _shortId,
+ promiseViewAd: promiseViewAd ?? _promiseViewAd,
+ videoUrl: videoUrl ?? _videoUrl,
+ coins: coins ?? _coins,
+ vipCoins: vipCoins ?? _vipCoins,
+ episode: episode ?? _episode,
+ isVip: isVip ?? _isVip,
+ revolution: revolution ?? _revolution,
+ imageUrl: imageUrl ?? _imageUrl,
+ );
+
+ num? get id => _id;
+
+ num? get shortPlayVideoId => _shortPlayVideoId;
+
+ num? get shortPlayId => _shortPlayId;
+
+ num? get shortId => _shortId;
+
+ num? get promiseViewAd => _promiseViewAd;
+
+ String? get videoUrl => _videoUrl;
+
+ num? get coins => _coins;
+
+ num? get vipCoins => _vipCoins;
+
+ num? get episode => _episode;
+
+ num? get isVip => _isVip;
+
+ Revolution? get revolution => _revolution;
+
+ String? get imageUrl => _imageUrl;
+
+ set id(num? value) => _id = value;
+
+ set shortPlayVideoId(num? value) => _shortPlayVideoId = value;
+
+ set shortPlayId(num? value) => _shortPlayId = value;
+
+ set shortId(num? value) => _shortId = value;
+
+ set promiseViewAd(num? value) => _promiseViewAd = value;
+
+ set videoUrl(String? value) => _videoUrl = value;
+
+ set coins(num? value) => _coins = value;
+
+ set vipCoins(num? value) => _vipCoins = value;
+
+ set episode(num? value) => _episode = value;
+
+ set isVip(num? value) => _isVip = value;
+
+ set revolution(Revolution? value) => _revolution = value;
+
+ set imageUrl(String? value) => _imageUrl = value;
+
+ Map toJson() {
+ final map = {};
+ map['id'] = _id;
+ map['short_play_video_id'] = _shortPlayVideoId;
+ map['short_play_id'] = _shortPlayId;
+ map['short_id'] = _shortId;
+ map['promise_view_ad'] = _promiseViewAd;
+ map['video_url'] = _videoUrl;
+ map['coins'] = _coins;
+ map['vip_coins'] = _vipCoins;
+ map['episode'] = _episode;
+ map['is_vip'] = _isVip;
+ if (_revolution != null) {
+ map['revolution'] = _revolution?.toJson();
+ }
+ map['image_url'] = _imageUrl;
+ return map;
+ }
+}
+
+/// r540 : "videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8"
+/// r720 : "videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8"
+/// r1080 : "videom3u8/a8ec99a023b074938e86/a8ec99a023b074938e86.m3u8"
+
+Revolution revolutionFromJson(String str) =>
+ Revolution.fromJson(json.decode(str));
+
+String revolutionToJson(Revolution data) => json.encode(data.toJson());
+
+class Revolution {
+ Revolution({String? r540, String? r720, String? r1080}) {
+ _r540 = r540;
+ _r720 = r720;
+ _r1080 = r1080;
+ }
+
+ Revolution.fromJson(dynamic json) {
+ _r540 = json['540'];
+ _r720 = json['720'];
+ _r1080 = json['1080'];
+ }
+
+ String? _r540;
+ String? _r720;
+ String? _r1080;
+
+ Revolution copyWith({String? r540, String? r720, String? r1080}) =>
+ Revolution(
+ r540: r540 ?? _r540,
+ r720: r720 ?? _r720,
+ r1080: r1080 ?? _r1080,
+ );
+
+ String? get r540 => _r540;
+
+ String? get r720 => _r720;
+
+ String? get r1080 => _r1080;
+
+ set r540(String? value) => _r540 = value;
+
+ set r720(String? value) => _r720 = value;
+
+ set r1080(String? value) => _r1080 = value;
+
+ Map toJson() {
+ final map = {};
+ map['r540'] = _r540;
+ map['r720'] = _r720;
+ map['r1080'] = _r1080;
+ return map;
+ }
+}
diff --git a/lib/kt_model/kt_user_info.dart b/lib/kt_model/kt_user_info.dart
new file mode 100644
index 0000000..0ccbbd6
--- /dev/null
+++ b/lib/kt_model/kt_user_info.dart
@@ -0,0 +1,246 @@
+import 'dart:convert';
+
+/// id : "S101810"
+/// customer_id : "S101810"
+/// is_guide_vip : false
+/// is_tourist : true
+/// family_name : "Visitor"
+/// giving_name : ""
+/// vip_end_time : 0
+/// third_access_id : ""
+/// is_vip : false
+/// coin_left_total : 0
+/// vip_type : ""
+/// email : ""
+/// third_access_platform : ""
+/// ip_address : "220.202.113.86"
+/// country_code : "CN"
+/// user_level : "normal"
+/// send_coin_left_total : 0
+/// avator : ""
+/// sign_in_status : 0
+/// registered_days : 1
+/// ln : "cf9f5896322a374004754032700aef183a879ecbf0004aa546f3810d56672155"
+/// country : "9fc4508238942e7cf40354d962db0c18c5ceec7320e0a3b9f69a0a7836efa50c"
+
+KtUserInfo ktUserInfoFromJson(String str) =>
+ KtUserInfo.fromJson(json.decode(str));
+
+String ktUserInfoToJson(KtUserInfo data) => json.encode(data.toJson());
+
+class KtUserInfo {
+ KtUserInfo({
+ String? id,
+ String? customerId,
+ bool? isGuideVip,
+ bool? isTourist,
+ String? familyName,
+ String? givingName,
+ int? vipEndTime,
+ String? thirdAccessId,
+ bool? isVip,
+ num? coinLeftTotal,
+ String? vipType,
+ String? email,
+ String? thirdAccessPlatform,
+ String? ipAddress,
+ String? countryCode,
+ String? userLevel,
+ num? sendCoinLeftTotal,
+ String? avator,
+ num? signInStatus,
+ num? registeredDays,
+ String? ln,
+ String? country,
+ }) {
+ _id = id;
+ _customerId = customerId;
+ _isGuideVip = isGuideVip;
+ _isTourist = isTourist;
+ _familyName = familyName;
+ _givingName = givingName;
+ _vipEndTime = vipEndTime;
+ _thirdAccessId = thirdAccessId;
+ _isVip = isVip;
+ _coinLeftTotal = coinLeftTotal;
+ _vipType = vipType;
+ _email = email;
+ _thirdAccessPlatform = thirdAccessPlatform;
+ _ipAddress = ipAddress;
+ _countryCode = countryCode;
+ _userLevel = userLevel;
+ _sendCoinLeftTotal = sendCoinLeftTotal;
+ _avator = avator;
+ _signInStatus = signInStatus;
+ _registeredDays = registeredDays;
+ _ln = ln;
+ _country = country;
+ }
+
+ KtUserInfo.fromJson(dynamic json) {
+ _id = json['id'];
+ _customerId = json['customer_id'];
+ _isGuideVip = json['is_guide_vip'];
+ _isTourist = json['is_tourist'];
+ _familyName = json['family_name'];
+ _givingName = json['giving_name'];
+ _vipEndTime = json['vip_end_time'];
+ _thirdAccessId = json['third_access_id'];
+ _isVip = json['is_vip'];
+ _coinLeftTotal = json['coin_left_total'];
+ _vipType = json['vip_type'];
+ _email = json['email'];
+ _thirdAccessPlatform = json['third_access_platform'];
+ _ipAddress = json['ip_address'];
+ _countryCode = json['country_code'];
+ _userLevel = json['user_level'];
+ _sendCoinLeftTotal = json['send_coin_left_total'];
+ _avator = json['avator'];
+ _signInStatus = json['sign_in_status'];
+ _registeredDays = json['registered_days'];
+ _ln = json['ln'];
+ _country = json['country'];
+ }
+
+ String? _id;
+ String? _customerId;
+ bool? _isGuideVip;
+ bool? _isTourist;
+ String? _familyName;
+ String? _givingName;
+ int? _vipEndTime;
+ String? _thirdAccessId;
+ bool? _isVip;
+ num? _coinLeftTotal;
+ String? _vipType;
+ String? _email;
+ String? _thirdAccessPlatform;
+ String? _ipAddress;
+ String? _countryCode;
+ String? _userLevel;
+ num? _sendCoinLeftTotal;
+ String? _avator;
+ num? _signInStatus;
+ num? _registeredDays;
+ String? _ln;
+ String? _country;
+
+ KtUserInfo copyWith({
+ String? id,
+ String? customerId,
+ bool? isGuideVip,
+ bool? isTourist,
+ String? familyName,
+ String? givingName,
+ int? vipEndTime,
+ String? thirdAccessId,
+ bool? isVip,
+ num? coinLeftTotal,
+ String? vipType,
+ String? email,
+ String? thirdAccessPlatform,
+ String? ipAddress,
+ String? countryCode,
+ String? userLevel,
+ num? sendCoinLeftTotal,
+ String? avator,
+ num? signInStatus,
+ num? registeredDays,
+ String? ln,
+ String? country,
+ }) => KtUserInfo(
+ id: id ?? _id,
+ customerId: customerId ?? _customerId,
+ isGuideVip: isGuideVip ?? _isGuideVip,
+ isTourist: isTourist ?? _isTourist,
+ familyName: familyName ?? _familyName,
+ givingName: givingName ?? _givingName,
+ vipEndTime: vipEndTime ?? _vipEndTime,
+ thirdAccessId: thirdAccessId ?? _thirdAccessId,
+ isVip: isVip ?? _isVip,
+ coinLeftTotal: coinLeftTotal ?? _coinLeftTotal,
+ vipType: vipType ?? _vipType,
+ email: email ?? _email,
+ thirdAccessPlatform: thirdAccessPlatform ?? _thirdAccessPlatform,
+ ipAddress: ipAddress ?? _ipAddress,
+ countryCode: countryCode ?? _countryCode,
+ userLevel: userLevel ?? _userLevel,
+ sendCoinLeftTotal: sendCoinLeftTotal ?? _sendCoinLeftTotal,
+ avator: avator ?? _avator,
+ signInStatus: signInStatus ?? _signInStatus,
+ registeredDays: registeredDays ?? _registeredDays,
+ ln: ln ?? _ln,
+ country: country ?? _country,
+ );
+
+ String? get id => _id;
+
+ String? get customerId => _customerId;
+
+ bool? get isGuideVip => _isGuideVip;
+
+ bool? get isTourist => _isTourist;
+
+ String? get familyName => _familyName;
+
+ String? get givingName => _givingName;
+
+ int? get vipEndTime => _vipEndTime;
+
+ String? get thirdAccessId => _thirdAccessId;
+
+ bool? get isVip => _isVip;
+
+ num? get coinLeftTotal => _coinLeftTotal;
+
+ String? get vipType => _vipType;
+
+ String? get email => _email;
+
+ String? get thirdAccessPlatform => _thirdAccessPlatform;
+
+ String? get ipAddress => _ipAddress;
+
+ String? get countryCode => _countryCode;
+
+ String? get userLevel => _userLevel;
+
+ num? get sendCoinLeftTotal => _sendCoinLeftTotal;
+
+ String? get avator => _avator;
+
+ num? get signInStatus => _signInStatus;
+
+ num? get registeredDays => _registeredDays;
+
+ String? get ln => _ln;
+
+ String? get country => _country;
+
+ Map toJson() {
+ final map = {};
+ map['id'] = _id;
+ map['customer_id'] = _customerId;
+ map['is_guide_vip'] = _isGuideVip;
+ map['is_tourist'] = _isTourist;
+ map['family_name'] = _familyName;
+ map['giving_name'] = _givingName;
+ map['vip_end_time'] = _vipEndTime;
+ map['third_access_id'] = _thirdAccessId;
+ map['is_vip'] = _isVip;
+ map['coin_left_total'] = _coinLeftTotal;
+ map['vip_type'] = _vipType;
+ map['email'] = _email;
+ map['third_access_platform'] = _thirdAccessPlatform;
+ map['ip_address'] = _ipAddress;
+ map['country_code'] = _countryCode;
+ map['user_level'] = _userLevel;
+ map['send_coin_left_total'] = _sendCoinLeftTotal;
+ map['avator'] = _avator;
+ map['sign_in_status'] = _signInStatus;
+ map['registered_days'] = _registeredDays;
+ map['ln'] = _ln;
+ map['country'] = _country;
+ return map;
+ }
+}
diff --git a/lib/kt_pages/kt_explore/view.dart b/lib/kt_pages/kt_explore/view.dart
new file mode 100644
index 0000000..403cd5d
--- /dev/null
+++ b/lib/kt_pages/kt_explore/view.dart
@@ -0,0 +1,15 @@
+import 'package:flutter/material.dart';
+
+class KtExplorePage extends StatefulWidget {
+ const KtExplorePage({super.key});
+
+ @override
+ State createState() => _KtExplorePageState();
+}
+
+class _KtExplorePageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return const Scaffold();
+ }
+}
diff --git a/lib/kt_pages/kt_home/logic.dart b/lib/kt_pages/kt_home/logic.dart
new file mode 100644
index 0000000..0c39054
--- /dev/null
+++ b/lib/kt_pages/kt_home/logic.dart
@@ -0,0 +1,88 @@
+import 'package:flutter_kinetra/kt_pages/kt_home/state.dart';
+import 'package:get/get.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+
+import '../../dio_cilent/kt_apis.dart';
+import '../../dio_cilent/kt_request.dart';
+import '../../kt_model/kt_short_video_bean.dart';
+import '../../kt_widgets/kt_status_widget.dart';
+
+class KtHomeLogic extends GetxController {
+ final state = KtHomeState();
+
+ @override
+ void onReady() {
+ // TODO: implement onReady
+ super.onReady();
+ getHomeInfo();
+ }
+
+ getHomeInfo({RefreshController? refreshCtrl}) async {
+ state.loadStatus = KtLoadStatusType.loading;
+ try {
+ ApiResponse res = await HttpClient().request(
+ KtApis.homeAllModules,
+ method: HttpMethod.get,
+ );
+ refreshCtrl?.refreshCompleted();
+
+ if (res.success) {
+ state.loadStatus = KtLoadStatusType.loadSuccess;
+ res.data['list'].forEach((item) {
+ if (item['module_key'] == 'home_banner') {
+ state.bannerList = [
+ ...item['data']
+ .map(
+ (item) =>
+ KtShortVideoBean.fromJson(item as Map),
+ )
+ .toList(),
+ ];
+ } else if (item['module_key'] == 'highest_payment_hot_video') {
+ state.topPickList = [
+ ...item['data']
+ .map(
+ (item) =>
+ KtShortVideoBean.fromJson(item as Map),
+ )
+ .toList(),
+ ];
+ } else if (item['module_key'] == 'new_recommand') {
+ state.arrivalList = [
+ ...item['data']['list']
+ .map(
+ (item) =>
+ KtShortVideoBean.fromJson(item as Map),
+ )
+ .toList(),
+ ];
+ } else if (item['module_key'] == 'week_highest_recommend') {
+ state.trendingList = [
+ ...item['data']
+ .map(
+ (item) =>
+ KtShortVideoBean.fromJson(item as Map),
+ )
+ .toList(),
+ ];
+ int halfLength = state.trendingList.length ~/ 2;
+ state.trendingTopList = state.trendingList.sublist(0, halfLength);
+ state.trendingBottomList = state.trendingList.sublist(halfLength);
+ }
+ });
+
+ if (state.trendingList.isEmpty &&
+ state.bannerList.isEmpty &&
+ state.arrivalList.isEmpty) {
+ state.loadStatus = KtLoadStatusType.loadNoData;
+ }
+ } else {
+ state.loadStatus = KtLoadStatusType.loadFailed;
+ }
+ update();
+ } catch (e) {
+ state.loadStatus = KtLoadStatusType.loadFailed;
+ update();
+ }
+ }
+}
diff --git a/lib/kt_pages/kt_home/state.dart b/lib/kt_pages/kt_home/state.dart
new file mode 100644
index 0000000..8c64901
--- /dev/null
+++ b/lib/kt_pages/kt_home/state.dart
@@ -0,0 +1,17 @@
+import '../../kt_model/kt_short_video_bean.dart';
+import '../../kt_widgets/kt_status_widget.dart';
+
+class KtHomeState {
+ KtLoadStatusType loadStatus = KtLoadStatusType.loading;
+ List topPickList = [];
+ List trendingList = [];
+ List trendingTopList = [];
+ List trendingBottomList = [];
+ List arrivalList = [];
+ List bannerList = [];
+
+ bool showVideo = true;
+ bool hasSubCoin = false;
+ int receiveCoin = 0;
+ KtShortVideoBean? curVideo;
+}
diff --git a/lib/kt_pages/kt_home/view.dart b/lib/kt_pages/kt_home/view.dart
new file mode 100644
index 0000000..4c71d92
--- /dev/null
+++ b/lib/kt_pages/kt_home/view.dart
@@ -0,0 +1,157 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_kinetra/kt_pages/kt_home/logic.dart';
+import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+
+class KtHomePage extends StatefulWidget {
+ const KtHomePage({super.key});
+
+ @override
+ State createState() => _KtHomePageState();
+}
+
+class _KtHomePageState extends State {
+ final logic = Get.put(KtHomeLogic());
+ final state = Get.find().state;
+ @override
+ Widget build(BuildContext context) {
+ return GetBuilder(
+ assignId: true,
+ builder: (logic) {
+ return Stack(
+ children: [
+ Container(
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ padding: EdgeInsets.only(top: kToolbarHeight),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('bg1.png'.ktIcon),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Column(
+ children: [
+ Container(
+ padding: EdgeInsets.symmetric(horizontal: 15.w),
+ margin: EdgeInsets.only(top: 20.w),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Container(
+ width: 235.w,
+ height: 22.w,
+ padding: EdgeInsets.only(right: 7.w),
+ alignment: Alignment.centerRight,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('home_top_slogan.png'.ktIcon),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Text(
+ 'Get Hooked in Seconds',
+ style: TextStyle(
+ fontSize: 12.sp,
+ fontWeight: FontWeight.w600,
+ fontStyle: FontStyle.italic,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ Image.asset('ic_search.png'.ktIcon, width: 34.w),
+ ],
+ ),
+ ),
+ Container(
+ width: ScreenUtil().screenWidth,
+ height: 129.h,
+ padding: EdgeInsets.fromLTRB(29.w, 32.w, 17.w, 15.h),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('home_top.png'.ktIcon),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Row(
+ children: [
+ Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Stack(
+ alignment: Alignment.bottomCenter,
+ children: [
+ Image.asset(
+ 'text_bg.png'.ktIcon,
+ height: 17.w,
+ ),
+ Text(
+ 'Trend Cyclone',
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Color(0xFF1E1E20),
+ fontWeight: FontWeight.w800,
+ ),
+ ),
+ ],
+ ),
+ Image.asset('ic_right.png'.ktIcon, width: 10.w),
+ ],
+ ),
+ SizedBox(height: 5.w),
+ Text(
+ 'Everyone\'s Watching',
+ style: TextStyle(
+ fontSize: 12.sp,
+ fontWeight: FontWeight.w400,
+ color: Color(0xFFAEAEAE),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(width: 17.w),
+ Container(
+ child: Column(
+ children: [
+ Row(
+ children: [
+ Image.asset(
+ 'ic_star.png'.ktIcon,
+ width: 14.w,
+ ),
+ SizedBox(width: 4.w),
+
+ SizedBox(
+ width: 162.w,
+ child: Text(
+ 'rebirth: power and beauty',
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(
+ fontSize: 13.sp,
+ color: Colors.black,
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ },
+ );
+ }
+}
diff --git a/lib/kt_pages/kt_main_page/logic.dart b/lib/kt_pages/kt_main_page/logic.dart
new file mode 100644
index 0000000..e69de29
diff --git a/lib/kt_pages/kt_main_page/state.dart b/lib/kt_pages/kt_main_page/state.dart
new file mode 100644
index 0000000..e69de29
diff --git a/lib/kt_pages/kt_main_page/view.dart b/lib/kt_pages/kt_main_page/view.dart
new file mode 100644
index 0000000..4cdb464
--- /dev/null
+++ b/lib/kt_pages/kt_main_page/view.dart
@@ -0,0 +1,332 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+
+import '../../kt_utils/kt_keys.dart';
+import '../kt_explore/view.dart';
+import '../kt_home/view.dart';
+import '../kt_mine/view.dart';
+import '../kt_my_list/view.dart';
+
+class KtMainPage extends StatefulWidget {
+ const KtMainPage({super.key});
+
+ @override
+ State createState() => _KtMainPageState();
+}
+
+class _KtMainPageState extends State
+ with RouteAware, WidgetsBindingObserver {
+ final PageController _controller = PageController();
+ static const List _tabsTitle = [
+ {'icon': 'home', 'title': 'Home'},
+ {'icon': 'explore', 'title': 'Explore'},
+ {'icon': 'favorite', 'title': 'My List'},
+ {'icon': 'mine', 'title': 'Profile'},
+ ];
+
+ int _currentIndex = 0;
+
+ // 只在需要时构建tab页面
+ final Map _tabCache = {};
+
+ Widget _getTab(int index) {
+ if (_tabCache.containsKey(index)) return _tabCache[index]!;
+ late Widget tab;
+ switch (index) {
+ case 0:
+ tab = const KtHomePage();
+ break;
+ case 1:
+ tab = const KtExplorePage();
+ break;
+ case 2:
+ tab = const KtMyListPage();
+ break;
+ case 3:
+ tab = const KtMinePage();
+ break;
+ default:
+ tab = const SizedBox();
+ }
+ _tabCache[index] = tab;
+ return tab;
+ }
+
+ bool _pageOpen = false; //页面已打开
+ bool _isAndroidTwicePermission = false; //安卓第二次请求权限
+ DateTime? _cycleLifeTime;
+
+ @override
+ Widget build(BuildContext context) {
+ return PopScope(
+ canPop: false,
+ onPopInvokedWithResult: (didPop, result) async {
+ if (!didPop) {
+ const platform = MethodChannel('backChannel');
+ try {
+ await platform.invokeMethod('moveToBack');
+ } on PlatformException catch (e) {
+ debugPrint('---err:$e');
+ }
+ }
+ },
+ child: Scaffold(
+ body: PageView.builder(
+ controller: _controller,
+ physics: const NeverScrollableScrollPhysics(),
+ onPageChanged: (index) {
+ _currentIndex = index;
+ setState(() {});
+ },
+ itemBuilder: (context, index) => _getTab(index),
+ itemCount: _tabsTitle.length,
+ ),
+ bottomNavigationBar: BottomNavigationBar(
+ selectedItemColor: Color(0xFF1E1E20),
+ selectedLabelStyle: TextStyle(
+ fontSize: 10.sp,
+ fontWeight: FontWeight.w400,
+ ),
+ unselectedLabelStyle: TextStyle(
+ fontSize: 10.sp,
+ color: Color(0xFF95959C),
+ fontWeight: FontWeight.w400,
+ ),
+ type: BottomNavigationBarType.fixed,
+ currentIndex: _currentIndex,
+ onTap: (index) {
+ _currentIndex = index;
+ _controller.jumpToPage(index);
+ // final recommendLogic = Get.put(RecommendLogic());
+ // if (index != 1) {
+ // recommendLogic.videoCtrl?.pause();
+ // } else {
+ // recommendLogic.videoCtrl?.play();
+ // }
+ // recommendLogic.update();
+ },
+ items: [
+ ..._tabsTitle.map(
+ (item) => BottomNavigationBarItem(
+ icon: Container(
+ height: 24.w,
+ margin: EdgeInsets.only(top: 4.w),
+ alignment: Alignment.center,
+ child: Image.asset(
+ 'ic_${item['icon']}_unsel.png'.ktIcon,
+ width: 24.w,
+ ),
+ ),
+ activeIcon: Container(
+ margin: EdgeInsets.only(top: 4.w),
+ child: Image.asset(
+ 'ic_${item['icon']}_sel.png'.ktIcon,
+ width: 24.w,
+ height: 24.w,
+ ),
+ ),
+ label: item['title'],
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ @override
+ void initState() {
+ super.initState();
+
+ // // Future.microtask(() async {
+ // _initFirebase();
+ // _checkNotificationPermission();
+ // // });
+ //
+ // WidgetsBinding.instance.addPostFrameCallback((_) async {
+ // await Future.delayed(Duration(milliseconds: 2000));
+ // if (!_pageOpen) {
+ // _checkDeeplink();
+ // _restore();
+ // _pageOpen = true;
+ // }
+ // });
+ WidgetsBinding.instance.addObserver(this);
+ }
+
+ @override
+ void dispose() {
+ _controller.dispose();
+ WidgetsBinding.instance.removeObserver(this);
+ super.dispose();
+ }
+
+ // @override
+ // void didChangeAppLifecycleState(AppLifecycleState state) {
+ // super.didChangeAppLifecycleState(state);
+ // if (state == AppLifecycleState.paused) {
+ // _cycleLifeTime = DateTime.now();
+ // } else if (state == AppLifecycleState.resumed) {
+ // AppBadgePlus.updateBadge(0);
+ // final now = DateTime.now();
+ // final duration = now.difference(_cycleLifeTime ?? now);
+ // if ((duration.inMilliseconds > 3 || _isAndroidTwicePermission) && _pageOpen) {
+ // Future.delayed(const Duration(milliseconds: 1000)).then((_) {
+ // if (mounted) _checkDeeplink();
+ // });
+ // }
+ // _cycleLifeTime = null;
+ // }
+ // }
+ //
+ // void _checkDeeplink() {
+ // EasyThrottle.throttle('check-deeplink', Duration(seconds: 2), () async {
+ // try {
+ // // 获取deepling链接
+ // // final adjustProvider = context.read();
+ // final deepLink = AdjustService().deeplink ?? '';
+ // debugPrint('[CheckDeeplink] DEEPLINK链接: $deepLink');
+ // // 使用的原始链接和使用链接
+ // String useString = '';
+ // String useStr = '';
+ // //优先使用直链
+ // if (deepLink != '') {
+ // useString = deepLink;
+ // useStr = deepLink;
+ // // 清空deeplink
+ // AdjustService().clearDeeplink();
+ // debugPrint('----清理deeplink:${AdjustService().deeplink}');
+ // } else {
+ // // 获取剪贴板内容
+ // final clipboardData = await Clipboard.getData(Clipboard.kTextPlain);
+ // final clipboardString = clipboardData?.text ?? '';
+ // debugPrint('[CheckDeeplink] 剪贴板原始链接: $clipboardString');
+ // // 判断剪贴板内容是否为跳转链接并处理
+ // final clipboardStr =
+ // clipboardString != '' &&
+ // clipboardString.startsWith(Apis.W2A_PREFIX) &&
+ // clipboardString.contains(Apis.W2A_NAME)
+ // ? clipboardString.substring(Apis.W2A_PREFIX.length).trim()
+ // : '';
+ // debugPrint('[CheckDeeplink] 剪贴板处理链接: $clipboardStr');
+ // useString = clipboardString;
+ // useStr = clipboardStr;
+ // }
+ //
+ // // 使用链接
+ // if (useStr != '') {
+ // final uri = Uri.tryParse(useStr);
+ // Map params = uri!.queryParameters;
+ // // params.forEach((k, v) {
+ // // debugPrint('----key:$k value:$v');
+ // // });
+ //
+ // final shortPlayId = params['short_play_id'];
+ // final videoId = params['video_id'] ?? 0;
+ // if (shortPlayId?.isEmpty ?? false) {
+ // debugPrint('[CheckDeeplink] 链接中没有参数');
+ // return;
+ // }
+ // // 上报w2a
+ // HttpClient().request(Apis.uploadW2a, data: {"data": useString});
+ // debugPrint('[CheckDeeplink] 跳转链接: $useStr');
+ // debugPrint('[CheckDeeplink] 上报链接: $useString');
+ // debugPrint('---current route:${Get.currentRoute}');
+ // AdjustService().clearDeeplink();
+ // // 清空剪贴板
+ // await Clipboard.setData(const ClipboardData(text: ''));
+ // if (Get.currentRoute == AppRoutes.shortVideo) {
+ // // Get.offAndToNamed(
+ // // AppRoutes.shortVideo,
+ // // arguments: {'shortPlayId': int.parse(shortPlayId), "videoId": int.parse(videoId)},
+ // // );
+ // final logic = Get.put(ShortVideoLogic());
+ // logic.state.shortPlayId = int.parse(shortPlayId);
+ // logic.state.videoId = int.parse(videoId);
+ // logic.initData();
+ // } else {
+ // Get.toNamed(
+ // AppRoutes.shortVideo,
+ // arguments: {'shortPlayId': int.parse(shortPlayId.toString()), "videoId": int.parse(videoId.toString())},
+ // );
+ // }
+ // }
+ // } catch (e) {
+ // debugPrint('[AdjustManager] 读取剪贴板异常: $e');
+ // }
+ // });
+ // }
+ //
+ // _initFirebase() async {
+ // try {
+ // await Firebase.initializeApp();
+ // } catch (e) {
+ // debugPrint("----initFirebase err: $e");
+ // }
+ // if (Platform.isIOS) {
+ // await FirebaseIOS().initialize();
+ // } else if (Platform.isAndroid) {
+ // await FirebaseAndroid().initialize();
+ // await FirebaseAndroid().initializeNotifications();
+ // }
+ // // 获取初始消息(应用通过通知启动)看是否是应用消息启动
+ // if (Platform.isIOS) {
+ // WidgetsBinding.instance.addPostFrameCallback((timeStamp) async {
+ // // 看是否是消息跳进来,然后跳转到详情页面
+ // RemoteMessage? remoteMessage = await FirebaseMessaging.instance.getInitialMessage();
+ // debugPrint("杀死app启动通知:$remoteMessage");
+ // if (remoteMessage != null) {
+ // final msgData = remoteMessage.data as Map;
+ // final msgNotification = remoteMessage.notification;
+ // final String? msgId = msgData['msg_id'];
+ // final String title = msgNotification?.title ?? "";
+ // if (msgId != null) {
+ // HttpClient().request(Apis.sendMessageReport, data: {"message_id": int.parse(msgId), "title": title});
+ // }
+ // FirebaseCommon().onFirebaseRoute(msgData);
+ // }
+ // });
+ // }
+ // }
+ //
+ // // 检查通知权限
+ // Future _checkNotificationPermission() async {
+ // final permissionStatus = await Permission.notification.status;
+ // if (permissionStatus.isDenied) {
+ // if (Platform.isAndroid) {
+ // //安卓第二次请求权限,再次查询剪贴板的w2a链接
+ // _isAndroidTwicePermission = true;
+ // }
+ // //再次请求
+ // await Permission.notification.request();
+ // } else if (permissionStatus.isPermanentlyDenied) {
+ // int now = DateTime.now().millisecondsSinceEpoch;
+ // int lastRequestTime = SpUtils().getInt(SpKeys.notiPermissionTime) ?? now;
+ // int hours = DateTime.now().difference(DateTime.fromMillisecondsSinceEpoch(lastRequestTime)).inHours;
+ // if (hours < 24) return;
+ // SpUtils().setInt(SpKeys.notiPermissionTime, now);
+ // //永久拒绝
+ // Get.dialog(
+ // CommonDialog(
+ // topIconWidget: Positioned(
+ // left: -35.w,
+ // top: 0.w,
+ // child: Image.asset('ic_dialog_subscribe.png'.icon, width: 140.w, height: 100.w),
+ // ),
+ // title: 'Turn on Notifications?',
+ // subTitle: 'Get alerts for new episodes and exclusive offers.',
+ // hasLeftBtn: false,
+ // rightBtnText: 'Allow',
+ // rightBtnFunc: () => openAppSettings(),
+ // ),
+ // );
+ // }
+ // }
+ //
+ // _restore() async {
+ // await Get.put(MineLogic()).getUserInfo();
+ // EasyThrottle.throttle('restore', Duration(minutes: 5), () => BuyUtils.restorePay(showTips: false));
+ // }
+}
diff --git a/lib/kt_pages/kt_mine/insert_web/wallet_page.dart b/lib/kt_pages/kt_mine/insert_web/wallet_page.dart
new file mode 100644
index 0000000..c897cd1
--- /dev/null
+++ b/lib/kt_pages/kt_mine/insert_web/wallet_page.dart
@@ -0,0 +1,254 @@
+import 'dart:collection';
+import 'dart:convert';
+import 'dart:io';
+import 'package:flustars/flustars.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_inappwebview/flutter_inappwebview.dart';
+import 'package:flutter_kinetra/kt_pages/kt_routes.dart';
+import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart' hide ScreenUtil;
+import 'package:get/get.dart';
+
+import '../../../dio_cilent/kt_apis.dart';
+import '../../../kt_utils/kt_keys.dart';
+import '../../../kt_utils/kt_utils.dart';
+import '../../../main.dart';
+
+class WalletPage extends StatefulWidget {
+ const WalletPage({super.key});
+
+ @override
+ SignInActivityPageState createState() => SignInActivityPageState();
+}
+
+class SignInActivityPageState extends State with RouteAware {
+ InAppWebViewController? _webViewController;
+ late PullToRefreshController _webRefreshController;
+ late Map _userData;
+ // LoadStatusType loadingStatus = LoadStatusType.loading;
+
+ @override
+ void initState() {
+ super.initState();
+ _initUserData();
+ _initRefreshController();
+ }
+
+ void _initUserData() {
+ _userData = {
+ 'time_zone': KtUtils.getTimeZoneOffset(DateTime.now()),
+ 'type': Platform.isAndroid ? 'android' : 'ios',
+ 'lang': 'en',
+ 'theme': 'theme_7',
+ 'token': SpUtil.getString(KtKeys.token) ?? '',
+ };
+ print('-----userData:${_userData}');
+ }
+
+ _initRefreshController() {
+ _webRefreshController = PullToRefreshController(
+ settings: PullToRefreshSettings(enabled: true),
+ onRefresh: () async {
+ if (Platform.isAndroid) {
+ _webViewController?.reload();
+ } else if (Platform.isIOS) {
+ _webViewController?.loadUrl(
+ urlRequest: URLRequest(url: WebUri(KtApis.WEB_SITE_WALLET)),
+ );
+ }
+ },
+ );
+ }
+
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ routeObserver.subscribe(this, ModalRoute.of(context)! as PageRoute);
+ }
+
+ // 从别的路由回来
+ @override
+ void didPopNext() {
+ super.didPopNext();
+ _webViewController?.reload();
+ }
+
+ @override
+ void dispose() {
+ super.dispose();
+ _webViewController?.dispose();
+ }
+
+ // 处理传递的消息
+ void _handleWebMessage(String jsonS) async {
+ if (jsonS.isEmpty) return;
+
+ Map? webParams;
+
+ if (Platform.isAndroid) {
+ List params = jsonDecode(jsonS);
+ webParams = params[0];
+ } else if (Platform.isIOS) {
+ webParams = jsonDecode(jsonS);
+ }
+ if (webParams == null) {
+ debugPrint("没有获取到传递过来的参数");
+ return;
+ }
+
+ String actionType = webParams["type"];
+
+ switch (actionType) {
+ case 'goStore':
+ Get.toNamed(KtRoutes.store);
+ break;
+ default:
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ extendBodyBehindAppBar: true,
+ // appBar: AppBar(
+ // leading: Container(
+ // padding: EdgeInsets.only(left: 15.w, bottom: 6.w),
+ // child: IconButton(
+ // icon: Image.asset('ic_back.png'.ktIcon, width: 24.w),
+ // onPressed: () => Navigator.of(context).maybePop(),
+ // ),
+ // ),
+ // ),
+ body: Container(
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ padding: EdgeInsets.only(top: ScreenUtil().statusBarHeight + 20.w),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('bg1.png'.ktIcon),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Container(
+ margin: EdgeInsets.only(top: 16.w),
+ child: Stack(
+ children: [
+ InAppWebView(
+ pullToRefreshController: _webRefreshController,
+ initialSettings: InAppWebViewSettings(
+ cacheEnabled: false,
+ javaScriptEnabled: true,
+ alwaysBounceVertical: true,
+ allowsBackForwardNavigationGestures: true,
+ domStorageEnabled: false,
+ clearCache: true,
+ transparentBackground: true,
+ ),
+ // 注入两个handler
+ initialUserScripts: UnmodifiableListView([
+ UserScript(
+ source: """
+ window.AndroidInterface = {
+ getUserInfo: function() {
+ return window.flutter_inappwebview.callHandler('getUserInfo');
+ },
+ js2app: function(jsonS) {
+ return window.flutter_inappwebview.callHandler('js2app',jsonS);
+ }
+ };
+
+ """,
+ injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START,
+ ),
+ ]),
+ onWebViewCreated: (controller) async {
+ _webViewController = controller;
+ _webViewController?.addJavaScriptHandler(
+ handlerName: 'getUserInfo',
+ callback: (_) => jsonEncode(_userData),
+ );
+ if (Platform.isIOS) {
+ // ios
+ await _webViewController?.addWebMessageListener(
+ WebMessageListener(
+ jsObjectName: "js2app",
+ allowedOriginRules: {"*"},
+ onPostMessage:
+ (message, sourceOrigin, isMainFrame, replyProxy) {
+ if (message?.data != null) {
+ _handleWebMessage(message?.data);
+ }
+ },
+ ),
+ );
+ } else if (Platform.isAndroid) {
+ _webViewController?.addJavaScriptHandler(
+ handlerName: "js2app",
+ callback: (jsonS) {
+ if (jsonS.isNotEmpty) {
+ _handleWebMessage(jsonS.toString());
+ }
+ },
+ );
+ }
+ await _webViewController?.loadUrl(
+ urlRequest: URLRequest(url: WebUri(KtApis.WEB_SITE_WALLET)),
+ );
+ },
+ onLoadStart: (controller, url) {
+ setState(() {
+ // loadingStatus = LoadStatusType.loading;
+ });
+ },
+ onLoadStop: (controller, url) async {
+ // await _webViewController?.evaluateJavascript(
+ // source: '''
+ // document.body.style.backgroundColor = "transparent"
+ // document.style.backgroundColor = "transparent"
+ // ''',
+ // );
+ if (Platform.isIOS) {
+ String userJsonStr = jsonEncode(_userData);
+ Future.delayed(const Duration(seconds: 1)).then((_) {
+ controller.evaluateJavascript(
+ source:
+ '''
+ if(typeof window.receiveDataFromNative === 'function') {
+ window.receiveDataFromNative($userJsonStr);
+ }
+ ''',
+ );
+ });
+ } else if (Platform.isAndroid) {
+ await controller.evaluateJavascript(
+ source: """
+ window.AndroidInterface = {
+ getUserInfo: async function () {
+ return window.flutter_inappwebview.callHandler('getUserInfo');
+ },
+ };
+ """,
+ );
+ }
+ setState(() {
+ // loadingStatus = LoadStatusType.loadSuccess;
+ });
+ _webRefreshController.endRefreshing();
+ },
+ onReceivedError: (controller, request, error) {
+ _webRefreshController.endRefreshing();
+ Future.delayed(const Duration(milliseconds: 100)).then((_) {
+ setState(() {
+ // loadingStatus = LoadStatusType.loadFailed;
+ });
+ });
+ },
+ ),
+ // _buildWidget(),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/kt_pages/kt_mine/kt_store/view.dart b/lib/kt_pages/kt_mine/kt_store/view.dart
new file mode 100644
index 0000000..7ffd1a7
--- /dev/null
+++ b/lib/kt_pages/kt_mine/kt_store/view.dart
@@ -0,0 +1,17 @@
+import 'package:flutter/material.dart';
+
+class KtStorePage extends StatefulWidget {
+ const KtStorePage({super.key});
+
+ @override
+ State createState() => _KtStorePageState();
+}
+
+class _KtStorePageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return const Scaffold(
+ body: Text('Store', style: TextStyle(color: Colors.black)),
+ );
+ }
+}
diff --git a/lib/kt_pages/kt_mine/logic.dart b/lib/kt_pages/kt_mine/logic.dart
new file mode 100644
index 0000000..859afdf
--- /dev/null
+++ b/lib/kt_pages/kt_mine/logic.dart
@@ -0,0 +1,42 @@
+import 'package:flustars/flustars.dart';
+import 'package:flutter_kinetra/dio_cilent/kt_apis.dart';
+import 'package:flutter_kinetra/kt_pages/kt_mine/state.dart';
+import 'package:flutter_kinetra/kt_utils/kt_utils.dart';
+import 'package:get/get.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+
+import '../../dio_cilent/kt_request.dart';
+import '../../kt_model/kt_user_info.dart';
+import '../../kt_utils/kt_keys.dart';
+
+class KtMineLogic extends GetxController {
+ final state = KtMineState();
+
+ bool get isLogin =>
+ KtUtils.isNotEmpty(SpUtil.getString(KtKeys.token)) &&
+ !(state.userInfo.isTourist ?? false);
+ final RefreshController refreshController = RefreshController();
+
+ @override
+ void onReady() {
+ super.onReady();
+ getUserInfo();
+ }
+
+ getUserInfo() async {
+ try {
+ ApiResponse res = await HttpClient().request(
+ KtApis.getCustomerInfo,
+ method: HttpMethod.get,
+ );
+ refreshController.refreshCompleted();
+
+ if (res.success) {
+ state.userInfo = KtUserInfo.fromJson(res.data);
+ update();
+ }
+ } catch (e) {
+ refreshController.refreshCompleted();
+ }
+ }
+}
diff --git a/lib/kt_pages/kt_mine/state.dart b/lib/kt_pages/kt_mine/state.dart
new file mode 100644
index 0000000..3941cde
--- /dev/null
+++ b/lib/kt_pages/kt_mine/state.dart
@@ -0,0 +1,5 @@
+import '../../kt_model/kt_user_info.dart';
+
+class KtMineState {
+ KtUserInfo userInfo = KtUserInfo();
+}
diff --git a/lib/kt_pages/kt_mine/view.dart b/lib/kt_pages/kt_mine/view.dart
new file mode 100644
index 0000000..1219ec9
--- /dev/null
+++ b/lib/kt_pages/kt_mine/view.dart
@@ -0,0 +1,31 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_kinetra/kt_pages/kt_routes.dart';
+import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+
+class KtMinePage extends StatefulWidget {
+ const KtMinePage({super.key});
+
+ @override
+ State createState() => _KtMinePageState();
+}
+
+class _KtMinePageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: Container(
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ padding: EdgeInsets.only(top: kToolbarHeight),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('bg1.png'.ktIcon),
+ fit: BoxFit.fill,
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/kt_pages/kt_my_list/view.dart b/lib/kt_pages/kt_my_list/view.dart
new file mode 100644
index 0000000..9bd83f5
--- /dev/null
+++ b/lib/kt_pages/kt_my_list/view.dart
@@ -0,0 +1,15 @@
+import 'package:flutter/material.dart';
+
+class KtMyListPage extends StatefulWidget {
+ const KtMyListPage({super.key});
+
+ @override
+ State createState() => _KtMyListPageState();
+}
+
+class _KtMyListPageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return const Scaffold();
+ }
+}
diff --git a/lib/kt_pages/kt_routes.dart b/lib/kt_pages/kt_routes.dart
new file mode 100644
index 0000000..7279746
--- /dev/null
+++ b/lib/kt_pages/kt_routes.dart
@@ -0,0 +1,40 @@
+import 'package:get/get_navigation/src/routes/get_route.dart';
+
+import 'kt_main_page/view.dart';
+import 'kt_mine/insert_web/wallet_page.dart';
+import 'kt_mine/kt_store/view.dart';
+import 'kt_splash_page.dart';
+import 'kt_webview_page.dart';
+
+class KtRoutes {
+ static const String splash = '/';
+ static const String home = '/main';
+ static const String search = '/search';
+ static const String category = '/category';
+ static const String shortVideo = '/short_video';
+ static const String store = '/store';
+ static const String wallet = '/wallet';
+ static const String helpCenter = '/help_center';
+ static const String helpCenterList = '/help_center_list';
+ static const String helpCenterDetail = '/help_center_detail';
+ static const String webView = '/web_view';
+ static const String signInActivity = '/sign_in_activity';
+ static const String refill = '/refill';
+
+ static final routes = [
+ GetPage(name: splash, page: () => const KtSplashPage()),
+ GetPage(name: home, page: () => const KtMainPage()),
+ // GetPage(name: search, page: () => const SearchPage()),
+ // GetPage(name: category, page: () => const CategoryPage()),
+ // GetPage(name: shortVideo, page: () => const ShortVideoPage(), preventDuplicates: false),
+ GetPage(name: store, page: () => KtStorePage()),
+ GetPage(name: wallet, page: () => const WalletPage()),
+ // GetPage(name: helpCenter, page: () => const HelpCenterPage()),
+ // GetPage(name: helpCenterList, page: () => const HelpCenterListPage()),
+ // GetPage(name: helpCenterDetail, page: () => const HelpCenterDetailPage()),
+ GetPage(
+ name: webView,
+ page: () => const KtWebViewPage(url: 'url'),
+ ),
+ ];
+}
diff --git a/lib/kt_pages/kt_splash_page.dart b/lib/kt_pages/kt_splash_page.dart
new file mode 100644
index 0000000..fda705a
--- /dev/null
+++ b/lib/kt_pages/kt_splash_page.dart
@@ -0,0 +1,138 @@
+import 'dart:io';
+
+import 'package:flustars/flustars.dart' hide ScreenUtil;
+import 'package:flutter/material.dart';
+import 'package:flutter_kinetra/kt_pages/kt_routes.dart';
+import 'package:flutter_kinetra/kt_utils/kt_keys.dart';
+import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
+import 'package:flutter_kinetra/kt_utils/kt_utils.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:permission_handler/permission_handler.dart';
+
+import '../kt_utils/kt_user_utils.dart';
+
+class KtSplashPage extends StatefulWidget {
+ const KtSplashPage({super.key});
+
+ @override
+ State createState() => _KtSplashPageState();
+}
+
+class _KtSplashPageState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: Container(
+ padding: EdgeInsets.symmetric(horizontal: 15.sp),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ (SpUtil.getBool(KtKeys.isFirstIn) ?? false
+ ? 'splash_bg2.png'
+ : 'splash_bg.png')
+ .ktIcon,
+ ),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Visibility(
+ visible: !(SpUtil.getBool(KtKeys.isFirstIn) ?? false),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ GestureDetector(
+ onTap: () {
+ SpUtil.putBool(KtKeys.isFirstIn, true);
+ KtUserUtil().register();
+ },
+ child: Container(
+ width: 200.w,
+ margin: EdgeInsets.only(bottom: 110.h),
+ padding: EdgeInsets.only(top: 21.w, bottom: 30.w),
+ alignment: Alignment.center,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage('ic_splash_btn.png'.ktIcon),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Text(
+ 'Get start',
+ style: TextStyle(
+ fontSize: 16.sp,
+ color: Color(0xFF1E1E20),
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ // initHeader();
+ initRoute();
+ }
+
+ initRoute() async {
+ await Future.delayed(const Duration(milliseconds: 1000));
+ setState(() {});
+ // _requestPermission();
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ String? token = SpUtil.getString(KtKeys.token);
+ if (!token.isNullString) {
+ try {
+ // HttpClient()(token!);
+ // KtUserUtil().enterAppPost();
+ } catch (e) {
+ debugPrint('---err:$e');
+ }
+ Get.offNamed(KtRoutes.home);
+ setState(() {});
+ } else {
+ if (SpUtil.getBool(KtKeys.isFirstIn) ?? false) {
+ KtUserUtil().register();
+ }
+ }
+ });
+ }
+
+ // Future _requestPermission() async {
+ // if (Platform.isIOS) {
+ // _initTracking();
+ // } else if (Platform.isAndroid) {
+ // _getGoogleAdId();
+ // }
+ // await Permission.notification.request();
+ // }
+
+ // _initTracking() async {
+ // await AppTrackingTransparency.requestTrackingAuthorization();
+ // // 获取 IDFA(需授权同意后才能获取)
+ // final idfa = await AppTrackingTransparency.getAdvertisingIdentifier();
+ // SpUtils().setString(SpKeys.iosIDFA, idfa);
+ // }
+ //
+ // _getGoogleAdId() async {
+ // String? advertisingId;
+ // // Platform messages may fail, so we use a try/catch PlatformException.
+ // try {
+ // advertisingId = await AdvertisingId.id(true);
+ // } on PlatformException {
+ // advertisingId = null;
+ // }
+ // if (advertisingId != null) SpUtils().setString(SpKeys.googleAid, advertisingId);
+ //
+ // return advertisingId;
+ // }
+}
diff --git a/lib/kt_pages/kt_webview_page.dart b/lib/kt_pages/kt_webview_page.dart
new file mode 100644
index 0000000..ba7d370
--- /dev/null
+++ b/lib/kt_pages/kt_webview_page.dart
@@ -0,0 +1,43 @@
+import 'package:flutter/material.dart';
+import 'package:webview_flutter/webview_flutter.dart';
+
+class KtWebViewPage extends StatefulWidget {
+ final String url;
+ final String? title;
+
+ const KtWebViewPage({super.key, required this.url, this.title});
+
+ @override
+ State createState() => _KtWebViewPageState();
+}
+
+class _KtWebViewPageState extends State {
+ late final WebViewController _controller;
+ bool _isLoading = true;
+
+ @override
+ void initState() {
+ super.initState();
+ _controller = WebViewController()
+ ..setJavaScriptMode(JavaScriptMode.unrestricted)
+ ..setNavigationDelegate(
+ NavigationDelegate(
+ onPageFinished: (_) => setState(() => _isLoading = false),
+ ),
+ )
+ ..loadRequest(Uri.parse(widget.url));
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(title: Text(widget.title ?? '')),
+ body: Stack(
+ children: [
+ WebViewWidget(controller: _controller),
+ if (_isLoading) const Center(child: CircularProgressIndicator()),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/kt_utils/kt_device_info_utils.dart b/lib/kt_utils/kt_device_info_utils.dart
new file mode 100644
index 0000000..77d3ddb
--- /dev/null
+++ b/lib/kt_utils/kt_device_info_utils.dart
@@ -0,0 +1,205 @@
+import 'dart:io';
+
+import 'package:android_id/android_id.dart';
+import 'package:device_info_plus/device_info_plus.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_secure_storage/flutter_secure_storage.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+
+class KtDeviceInfoUtil {
+ static final KtDeviceInfoUtil _instance = KtDeviceInfoUtil._internal();
+
+ factory KtDeviceInfoUtil() => _instance;
+
+ KtDeviceInfoUtil._internal();
+
+ final DeviceInfoPlugin _deviceInfoPlugin = DeviceInfoPlugin();
+ late PackageInfo _packageInfo;
+
+ // 设备基本信息
+ String? _deviceId;
+ String? _deviceIdfv;
+ String? _deviceModel;
+ String? _systemType;
+ String? _deviceBrand;
+ String? _osVersion;
+ int? _osVersionSdkInt;
+ String? _appVersion;
+ String? _appBuildNumber;
+ double? _screenWidth;
+ double? _screenHeight;
+ double? _pixelRatio;
+ String? _languageCode;
+ bool? _isTablet;
+ bool? _isPhysicalDevice;
+ String? _packageName;
+
+ // 初始化
+ Future init() async {
+ try {
+ _packageInfo = await PackageInfo.fromPlatform();
+ _packageName = _packageInfo.packageName; // 获取包名
+ await _getDeviceInfo();
+ _getScreenInfo();
+ _getLanguageInfo();
+ } catch (e) {
+ debugPrint('获取设备信息失败: $e');
+ }
+ }
+
+ // 获取设备信息
+ Future _getDeviceInfo() async {
+ if (kIsWeb) {
+ _getWebDeviceInfo();
+ } else if (Platform.isAndroid) {
+ await _getAndroidDeviceInfo();
+ } else if (Platform.isIOS) {
+ await _getIosDeviceInfo();
+ }
+ }
+
+ // 获取Web设备信息
+ void _getWebDeviceInfo() async {
+ final webInfo = await _deviceInfoPlugin.webBrowserInfo;
+ _deviceId = webInfo.vendor ?? '';
+ _deviceModel = webInfo.hardwareConcurrency.toString();
+ _osVersion = webInfo.appVersion ?? '';
+ _appVersion = _packageInfo.version;
+ _appBuildNumber = _packageInfo.buildNumber;
+ _isPhysicalDevice = null; // Web平台无法确定
+ _systemType = 'web';
+ }
+
+ // 获取Android设备信息
+ Future _getAndroidDeviceInfo() async {
+ const androidIdPlugin = AndroidId();
+ final androidInfo = await _deviceInfoPlugin.androidInfo;
+ String? androidId = await androidIdPlugin.getId();
+
+ String deviceId = androidId ?? androidInfo.id;
+ _deviceId = deviceId;
+ _deviceModel = androidInfo.model;
+ _deviceBrand = androidInfo.brand;
+ _osVersion = androidInfo.version.release;
+ _osVersionSdkInt = androidInfo.version.sdkInt;
+ _appVersion = _packageInfo.version;
+ _appBuildNumber = _packageInfo.buildNumber;
+ _isTablet = androidInfo.isPhysicalDevice; // 安卓平板判断可能需要更复杂的逻辑
+ _isPhysicalDevice = androidInfo.isPhysicalDevice;
+ _systemType = 'android';
+ }
+
+ // 获取iOS设备信息
+ Future _getIosDeviceInfo() async {
+ final iosInfo = await _deviceInfoPlugin.iosInfo;
+ _deviceIdfv = iosInfo.identifierForVendor;
+ _deviceModel = iosInfo.model;
+ _deviceBrand = iosInfo.modelName;
+ _osVersion = iosInfo.systemVersion;
+ _appVersion = _packageInfo.version;
+ _appBuildNumber = _packageInfo.buildNumber;
+ _isTablet = iosInfo.model.toLowerCase().contains('ipad');
+ _isPhysicalDevice = iosInfo.isPhysicalDevice;
+ _systemType = 'ios';
+
+ final securityStorage = FlutterSecureStorage();
+ String? idFv = await securityStorage.read(key: 'identifierForVendor');
+ idFv ??= iosInfo.identifierForVendor;
+ if (idFv != null) {
+ await securityStorage.write(key: "identifierForVendor", value: idFv);
+ _deviceId = idFv;
+ }
+ }
+
+ // 获取屏幕信息
+ void _getScreenInfo() {
+ final mediaQueryData =
+ WidgetsBinding.instance.platformDispatcher.views.first;
+ _screenWidth =
+ mediaQueryData.physicalSize.width / mediaQueryData.devicePixelRatio;
+ _screenHeight =
+ mediaQueryData.physicalSize.height / mediaQueryData.devicePixelRatio;
+ _pixelRatio = mediaQueryData.devicePixelRatio;
+ }
+
+ // 获取语言信息
+ void _getLanguageInfo() {
+ _languageCode =
+ WidgetsBinding.instance.platformDispatcher.locale.languageCode;
+ }
+
+ // 公开获取信息的方法
+ String? get deviceId => _deviceId;
+
+ String? get deviceIdfv => _deviceIdfv;
+
+ String? get deviceModel => _deviceModel;
+
+ String? get systemType => _systemType;
+
+ String? get deviceBrand => _deviceBrand;
+
+ String? get osVersion => _osVersion;
+
+ int? get osVersionSdkInt => _osVersionSdkInt;
+
+ String? get appVersion => _appVersion;
+
+ String? get appBuildNumber => _appBuildNumber;
+
+ double? get screenWidth => _screenWidth;
+
+ double? get screenHeight => _screenHeight;
+
+ double? get pixelRatio => _pixelRatio;
+
+ String? get languageCode => _languageCode;
+
+ bool? get isTablet => _isTablet;
+
+ bool? get isPhysicalDevice => _isPhysicalDevice;
+
+ String? get packageName => _packageName;
+
+ // 打印所有设备信息
+ void printDeviceInfo() {
+ debugPrint('''
+设备信息:
+ 包名: $_packageName
+ 设备ID: $_deviceId
+ 设备型号: $_deviceModel
+ 设备品牌: $_deviceBrand
+ 操作系统版本: $_osVersion
+ 操作系统版本SDKInt: $_osVersionSdkInt
+ 应用版本: $_appVersion
+ 应用构建号: $_appBuildNumber
+ 屏幕宽度: $_screenWidth
+ 屏幕高度: $_screenHeight
+ 像素密度: $_pixelRatio
+ 语言代码: $_languageCode
+ 是否平板: $_isTablet
+ 是否物理设备: $_isPhysicalDevice
+ ''');
+ }
+
+ // 获取设备信息Map
+ Map toMap() {
+ return {
+ 'packageName': _packageName,
+ 'deviceId': _deviceId,
+ 'deviceModel': _deviceModel,
+ 'deviceBrand': _deviceBrand,
+ 'osVersion': _osVersion,
+ 'osVersionSdkInt': _osVersionSdkInt,
+ 'appVersion': _appVersion,
+ 'appBuildNumber': _appBuildNumber,
+ 'screenWidth': _screenWidth,
+ 'screenHeight': _screenHeight,
+ 'pixelRatio': _pixelRatio,
+ 'languageCode': _languageCode,
+ 'isTablet': _isTablet,
+ 'isPhysicalDevice': _isPhysicalDevice,
+ };
+ }
+}
diff --git a/lib/kt_utils/kt_keys.dart b/lib/kt_utils/kt_keys.dart
new file mode 100644
index 0000000..88c72b4
--- /dev/null
+++ b/lib/kt_utils/kt_keys.dart
@@ -0,0 +1,8 @@
+class KtKeys {
+ static String isFirstIn = 'isFirstIn';
+ static String token = 'token';
+ static const String searchHistoryList = 'searchHistoryList';
+ static const String iosIDFA = 'iosIDFA';
+ static const String googleAid = 'googleAid';
+ static const String notiPermissionTime = 'notiPermissionTime'; // 上次申请权限时间
+}
diff --git a/lib/kt_utils/kt_string_extend.dart b/lib/kt_utils/kt_string_extend.dart
new file mode 100644
index 0000000..023c0f9
--- /dev/null
+++ b/lib/kt_utils/kt_string_extend.dart
@@ -0,0 +1,39 @@
+extension AssetString on String {
+ String get ktIcon => "assets/$this";
+ // 截断字符串并添加省略号
+ String truncate(int maxLength) {
+ if (length <= maxLength) return this;
+ return '${substring(0, maxLength)}...';
+ }
+
+ // 首字母大写
+ String capitalize() {
+ if (isEmpty) return this;
+ return this[0].toUpperCase() + substring(1);
+ }
+
+ // 转为 int,失败返回 null
+ int? toIntOrNull() => int.tryParse(this);
+
+ // 转为 double,失败返回 null
+ double? toDoubleOrNull() => double.tryParse(this);
+
+ // 判断是否为数字
+ bool get isNumeric => double.tryParse(this) != null;
+
+ // 去除所有空白
+ String get removeAllWhitespace => replaceAll(RegExp(r'\s+'), '');
+}
+
+extension NullString on String? {
+ bool get isNullString => this == null || (this?.isEmpty ?? false);
+
+ // 安全截断
+ String safeTruncate(int maxLength) {
+ if (this == null) return '';
+ return this!.truncate(maxLength);
+ }
+
+ // 安全首字母大写
+ String get safeCapitalize => (this?.capitalize() ?? '');
+}
diff --git a/lib/kt_utils/kt_toast_utils.dart b/lib/kt_utils/kt_toast_utils.dart
new file mode 100644
index 0000000..027039d
--- /dev/null
+++ b/lib/kt_utils/kt_toast_utils.dart
@@ -0,0 +1,140 @@
+import 'package:bot_toast/bot_toast.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_spinkit/flutter_spinkit.dart';
+
+final class KtToastUtils {
+ KtToastUtils._();
+
+ static CancelFunc showError(String msg) {
+ return showToast(
+ msg,
+ icon: Icon(Icons.error, size: 13, color: Colors.white),
+ );
+ }
+
+ static CancelFunc showSuccess({String? placeholder}) {
+ return BotToast.showCustomLoading(
+ duration: const Duration(milliseconds: 1500),
+ clickClose: true,
+ backgroundColor: Colors.black38,
+ toastBuilder: (cancelFunc) {
+ return Container(
+ padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(4),
+ ),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Icon(Icons.check, size: 32, color: Color(0xFF55731B)),
+ SizedBox(height: 16),
+ Text(
+ placeholder ?? 'Success',
+ style: TextStyle(
+ fontSize: 14,
+ color: Color(0xFF55731B),
+ fontWeight: FontWeight.w600,
+ height: 1.2,
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ );
+ }
+
+ static CancelFunc showToast(
+ String msg, {
+ Widget? icon,
+ bool autoClose = true,
+ }) {
+ return BotToast.showCustomText(
+ crossPage: false,
+ align: const Alignment(0, -0.8),
+ duration: autoClose ? const Duration(milliseconds: 2000) : null,
+ onlyOne: true,
+ toastBuilder: (cancelFunc) {
+ return Container(
+ padding: EdgeInsets.symmetric(vertical: 18.w, horizontal: 24.w),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8.w),
+ ),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ if (icon != null) icon,
+ const SizedBox(width: 4),
+ Flexible(
+ child: Text(
+ msg,
+ style: TextStyle(
+ color: const Color(0xFF55731B),
+ fontSize: 16,
+ fontWeight: FontWeight.w500,
+ height: 0.75,
+ ),
+ overflow: TextOverflow.ellipsis,
+ strutStyle: const StrutStyle(
+ leading: 0,
+ forceStrutHeight: true,
+ ), // 让文字和图标对齐
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ );
+ }
+
+ static CancelFunc showLoading({
+ Duration? duration,
+ bool? clickClose,
+ String? placeholder,
+ Color? backgroundColor,
+ }) {
+ return BotToast.showCustomLoading(
+ duration: duration,
+ clickClose: clickClose ?? true,
+ backgroundColor: backgroundColor ?? Colors.black38,
+
+ toastBuilder: (cancelFunc) {
+ return Container(
+ padding: const EdgeInsets.symmetric(horizontal: 32, vertical: 16),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(4),
+ ),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SizedBox(
+ width: 32,
+ height: 32,
+ child: SpinKitDoubleBounce(color: Color(0xFF55731B)),
+ ),
+ SizedBox(height: 16),
+ Text(
+ placeholder ?? "Loading...",
+ style: TextStyle(
+ fontSize: 14,
+ color: Color(0xFF55731B),
+ fontWeight: FontWeight.w600,
+ height: 1.2,
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ );
+ }
+}
diff --git a/lib/kt_utils/kt_user_utils.dart b/lib/kt_utils/kt_user_utils.dart
new file mode 100644
index 0000000..b7cb469
--- /dev/null
+++ b/lib/kt_utils/kt_user_utils.dart
@@ -0,0 +1,172 @@
+import 'dart:async';
+
+import 'package:easy_debounce/easy_throttle.dart';
+import 'package:flustars/flustars.dart';
+import 'package:get/get.dart';
+import 'package:permission_handler/permission_handler.dart';
+
+import '../dio_cilent/kt_apis.dart';
+import '../dio_cilent/kt_request.dart';
+import '../kt_model/kt_register_bean.dart';
+import '../kt_pages/kt_mine/logic.dart';
+import '../kt_pages/kt_routes.dart';
+import 'kt_keys.dart';
+
+class KtUserUtil {
+ static final KtUserUtil _instance = KtUserUtil._internal();
+
+ factory KtUserUtil() => _instance;
+
+ KtUserUtil._internal();
+
+ String? get token => SpUtil.getString(KtKeys.token);
+
+ Timer? timer;
+
+ register({bool toHome = true}) async {
+ try {
+ ApiResponse res = await HttpClient().request(KtApis.register);
+ if (res.success) {
+ KtRegisterBean data = KtRegisterBean.fromJson(res.data);
+ SpUtil.putString(KtKeys.token, data.token ?? '');
+
+ HttpClient().setAuthToken(data.token ?? '');
+ if (toHome) Get.offNamed(KtRoutes.home);
+ KtUserUtil().enterAppPost();
+ // FirebaseCommon.reportFirebaseToken();
+ Get.put(KtMineLogic());
+ Get.find().getUserInfo();
+
+ return Future.value(true);
+ }
+ if (toHome) Get.offNamed(KtRoutes.home);
+ return Future.value(false);
+ } catch (e) {
+ if (toHome) Get.offNamed(KtRoutes.home);
+ return Future.value(false);
+ }
+ }
+
+ //每十分钟执行一次
+ void startOnline() {
+ enterAppPost();
+ cancelTimer();
+ timer = Timer.periodic(Duration(minutes: 10), (timer) {
+ onLinePost();
+ });
+ }
+
+ void cancelTimer() {
+ timer?.cancel();
+ }
+
+ //进入app上报
+ enterAppPost({int isOpenNotice = 0}) {
+ if (token == null) return;
+ if (SpUtil.containsKey(KtKeys.token) ?? false) {
+ EasyThrottle.throttle('enterAppPost', Duration(seconds: 1), () async {
+ await HttpClient().request(
+ KtApis.enterTheApp,
+ data: {'is_open_notice': isOpenNotice},
+ );
+ });
+ // await HttpClient().request(KtApis.enterTheApp, data: {"is_open_notice": isOpenNotice});
+ }
+ }
+
+ //在线上报
+ onLinePost() async {
+ if (token == null) return;
+
+ EasyThrottle.throttle('onLinePost', Duration(seconds: 1), () async {
+ await HttpClient().request(
+ KtApis.onLine,
+ data: {'PostAuthorization': token ?? ''},
+ );
+ });
+ }
+
+ //离线上报
+ offLinePost() async {
+ if (token == null) return;
+
+ EasyThrottle.throttle('offline', Duration(seconds: 1), () async {
+ await HttpClient().request(
+ KtApis.leaveApp,
+ data: {'PostAuthorization': token ?? ''},
+ );
+ });
+ }
+
+ //上报通知权限
+ void reportNotify() async {
+ if (token == null) return;
+ final permissionStatus = await Permission.notification.status;
+ if (permissionStatus.isDenied || permissionStatus.isPermanentlyDenied) {
+ await HttpClient().request(
+ KtApis.uploadNoticeStatus,
+ data: {'is_open_notice': 0},
+ );
+ } else if (permissionStatus.isGranted) {
+ await HttpClient().request(
+ KtApis.uploadNoticeStatus,
+ data: {'is_open_notice': 1},
+ );
+ }
+ }
+
+ // 上报firebase token
+ reportFirebaseToken(String token) async {
+ await HttpClient().request(
+ KtApis.reportFirebaseToken,
+ data: {"fcm_token": token},
+ );
+ }
+
+ // 上报firebase 消息
+ sendMessageReport(int id, String title) async {
+ await HttpClient().request(
+ KtApis.sendMessageReport,
+ data: {"message_id": id, "title": title},
+ );
+ }
+
+ // 上报错误信息
+ reportErrorEvent(
+ String eventName,
+ String eventKey, {
+ String? errMsg,
+ String? type,
+ String? orderCode,
+ String? transactionId,
+ num shortPlayId = 0,
+ num shortPlayVideoId = 0,
+ Map? extendData,
+ Map? payData,
+ }) async {
+ String? userId = Get.put(KtMineLogic()).state.userInfo.customerId;
+
+ Map params = {
+ "event_name": eventName,
+ "event_key": eventKey,
+ "userId": userId,
+ "short_play_id": shortPlayId,
+ "short_play_video_id": shortPlayVideoId,
+ };
+
+ if (type != null) params.putIfAbsent('type', () => type);
+ if (orderCode != null) params.putIfAbsent('order_code', () => orderCode);
+ if (payData != null) params.putIfAbsent('pay_data', () => payData);
+ if (transactionId != null)
+ params.putIfAbsent('transaction_id', () => transactionId);
+ if (extendData != null) params.addAll(extendData);
+ params.putIfAbsent('error_msg', () => errMsg);
+ HttpClient().request(KtApis.reportEvent, data: params);
+ }
+
+ static String payCallback = 'pay_callback';
+ static String payError = 'pay_error';
+ static String payRestore = 'pay_restore';
+ static String payPlatformTimeout = 'pay_platform_timeout';
+ static String videoError = 'video_error';
+}
diff --git a/lib/kt_utils/kt_utils.dart b/lib/kt_utils/kt_utils.dart
new file mode 100644
index 0000000..aa1c4ff
--- /dev/null
+++ b/lib/kt_utils/kt_utils.dart
@@ -0,0 +1,21 @@
+class KtUtils {
+ static String getTimeZoneOffset(DateTime dateTime) {
+ Duration offset = dateTime.timeZoneOffset;
+ String sign = offset.isNegative ? '-' : '+';
+ int hours = offset.inHours.abs();
+ int minutes = (offset.inMinutes.abs() % 60);
+
+ return 'GMT$sign${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}';
+ }
+
+ static bool isEmpty(dynamic value) {
+ return value == null ||
+ (value is Map && value.isEmpty) ||
+ (value is String && value.isEmpty) ||
+ (value is Iterable && value.isEmpty);
+ }
+
+ static bool isNotEmpty(dynamic value) {
+ return !isEmpty(value);
+ }
+}
diff --git a/lib/kt_widgets/kt_high_light_text.dart b/lib/kt_widgets/kt_high_light_text.dart
new file mode 100644
index 0000000..8e8da83
--- /dev/null
+++ b/lib/kt_widgets/kt_high_light_text.dart
@@ -0,0 +1,243 @@
+import 'package:flutter/material.dart';
+
+class KtTextHighlightUtils {
+ /// 高亮搜索结果(支持正则匹配)
+ static TextSpan highlightSearchResult({
+ required String text,
+ required String searchTerm,
+ TextStyle? normalStyle,
+ TextStyle? highlightStyle,
+ bool caseSensitive = false,
+ }) {
+ if (searchTerm.isEmpty ||
+ !text.toLowerCase().contains(searchTerm.toLowerCase())) {
+ return TextSpan(text: text, style: normalStyle);
+ }
+
+ final matches = RegExp(
+ searchTerm,
+ caseSensitive: caseSensitive,
+ ).allMatches(text);
+
+ final List children = [];
+ int lastEnd = 0;
+
+ for (final match in matches) {
+ // 添加匹配前的文本
+ if (match.start > lastEnd) {
+ children.add(
+ TextSpan(
+ text: text.substring(lastEnd, match.start),
+ style: normalStyle,
+ ),
+ );
+ }
+
+ // 添加匹配的文本(高亮) - 修改为文本颜色区分
+ children.add(
+ TextSpan(
+ text: text.substring(match.start, match.end),
+ style:
+ highlightStyle ??
+ TextStyle(
+ color: Colors.blue, // 默认使用蓝色文本
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ );
+
+ lastEnd = match.end;
+ }
+
+ // 添加剩余的文本
+ if (lastEnd < text.length) {
+ children.add(TextSpan(text: text.substring(lastEnd), style: normalStyle));
+ }
+
+ return TextSpan(children: children);
+ }
+
+ /// 高亮文本(简单子字符串匹配)
+ static TextSpan highlightText({
+ required String text,
+ required String keyword,
+ Color highlightColor = Colors.blue, // 修改为文本颜色
+ Color textColor = Colors.black,
+ double fontSize = 16,
+ FontWeight normalWeight = FontWeight.normal,
+ FontWeight highlightWeight = FontWeight.bold,
+ bool caseSensitive = false,
+ String? fontFamily,
+ }) {
+ if (keyword.isEmpty) {
+ return TextSpan(
+ text: text,
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontWeight: normalWeight,
+ ),
+ );
+ }
+
+ final String searchText = caseSensitive ? text : text.toLowerCase();
+ final String searchKeyword = caseSensitive
+ ? keyword
+ : keyword.toLowerCase();
+
+ if (!searchText.contains(searchKeyword)) {
+ return TextSpan(
+ text: text,
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontWeight: normalWeight,
+ fontFamily: fontFamily,
+ ),
+ );
+ }
+
+ final List children = [];
+ int startIndex = 0;
+
+ while (startIndex < text.length) {
+ final int matchIndex = searchText.indexOf(searchKeyword, startIndex);
+
+ if (matchIndex == -1) {
+ // 剩余文本无匹配,全部添加
+ children.add(
+ TextSpan(
+ text: text.substring(startIndex),
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontWeight: normalWeight,
+ fontFamily: fontFamily,
+ ),
+ ),
+ );
+ break;
+ }
+
+ // 添加匹配前的文本
+ if (matchIndex > startIndex) {
+ children.add(
+ TextSpan(
+ text: text.substring(startIndex, matchIndex),
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontWeight: normalWeight,
+ fontFamily: fontFamily,
+ ),
+ ),
+ );
+ }
+
+ // 添加匹配的文本(高亮) - 修改为文本颜色区分
+ children.add(
+ TextSpan(
+ text: text.substring(matchIndex, matchIndex + keyword.length),
+ style: TextStyle(
+ color: highlightColor, // 使用指定的高亮文本颜色
+ fontSize: fontSize,
+ fontWeight: highlightWeight,
+ fontFamily: fontFamily,
+ ),
+ ),
+ );
+
+ // 更新起始位置
+ startIndex = matchIndex + keyword.length;
+ }
+
+ return TextSpan(children: children);
+ }
+
+ /// 高亮多个关键词
+ static TextSpan highlightMultipleKeywords({
+ required String text,
+ required List keywords,
+ Color highlightColor = Colors.blue, // 修改为文本颜色
+ Color textColor = Colors.black,
+ double fontSize = 16,
+ String? fontFamily,
+ }) {
+ if (keywords.isEmpty || text.isEmpty) {
+ return TextSpan(
+ text: text,
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontFamily: fontFamily,
+ ),
+ );
+ }
+
+ // 创建一个包含所有关键词的正则表达式
+ final regexPattern = keywords.map(RegExp.escape).join('|');
+ final regex = RegExp(regexPattern, caseSensitive: false);
+
+ final matches = regex.allMatches(text);
+ if (matches.isEmpty) {
+ return TextSpan(
+ text: text,
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontFamily: fontFamily,
+ ),
+ );
+ }
+
+ final List children = [];
+ int lastEnd = 0;
+
+ for (final match in matches) {
+ // 添加匹配前的文本
+ if (match.start > lastEnd) {
+ children.add(
+ TextSpan(
+ text: text.substring(lastEnd, match.start),
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontFamily: fontFamily,
+ ),
+ ),
+ );
+ }
+
+ // 添加匹配的文本(高亮) - 修改为文本颜色区分
+ children.add(
+ TextSpan(
+ text: text.substring(match.start, match.end),
+ style: TextStyle(
+ color: highlightColor, // 使用指定的高亮文本颜色
+ fontSize: fontSize,
+ fontWeight: FontWeight.bold,
+ fontFamily: fontFamily,
+ ),
+ ),
+ );
+
+ lastEnd = match.end;
+ }
+
+ // 添加剩余的文本
+ if (lastEnd < text.length) {
+ children.add(
+ TextSpan(
+ text: text.substring(lastEnd),
+ style: TextStyle(
+ color: textColor,
+ fontSize: fontSize,
+ fontFamily: fontFamily,
+ ),
+ ),
+ );
+ }
+
+ return TextSpan(children: children);
+ }
+}
diff --git a/lib/kt_widgets/kt_status_widget.dart b/lib/kt_widgets/kt_status_widget.dart
new file mode 100644
index 0000000..a41ede8
--- /dev/null
+++ b/lib/kt_widgets/kt_status_widget.dart
@@ -0,0 +1,107 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_kinetra/kt_utils/kt_string_extend.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+
+enum KtErrorStatusType { noNetwork, loadFailed, nothingYet, notFound }
+
+enum KtLoadStatusType { loading, loadSuccess, loadFailed, loadNoData }
+
+class BadStatusWidget extends StatelessWidget {
+ final KtErrorStatusType type;
+ final String? message;
+ final VoidCallback? onPressed;
+
+ const BadStatusWidget({
+ super.key,
+ required this.type,
+ this.message,
+ this.onPressed,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ return Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Stack(
+ alignment: Alignment.bottomCenter,
+ children: [
+ Image.asset(_getIcon(type).ktIcon, width: 290.w, height: 268.h),
+ Text(
+ _getMessage(type, message),
+ style: TextStyle(
+ fontSize: 15.sp,
+ color: Color(0xFF1E1E20),
+ fontWeight: FontWeight.w500,
+ ),
+ ),
+ ],
+ ),
+
+ Text(
+ _getSubMessage(type, message),
+ style: TextStyle(fontSize: 12.sp, color: Color(0xFF5E5E5E)),
+ ),
+ if (onPressed != null)
+ GestureDetector(
+ onTap: onPressed,
+ child: Container(
+ height: 48.h,
+ width: 200.w,
+ margin: EdgeInsets.only(top: 30.h),
+ alignment: Alignment.center,
+ decoration: BoxDecoration(
+ border: Border.all(color: Color(0xFF5E5E5E), width: 1.w),
+ borderRadius: BorderRadius.circular(50.w),
+ ),
+ child: Text(
+ 'Try Again',
+ style: TextStyle(fontSize: 14.sp, color: Color(0xFF1E1E20)),
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ String _getIcon(KtErrorStatusType type) {
+ switch (type) {
+ case KtErrorStatusType.noNetwork:
+ return 'ic_no_network.png';
+ case KtErrorStatusType.loadFailed:
+ return 'ic_load_failed.png';
+ case KtErrorStatusType.nothingYet:
+ return 'ic_nothing.png';
+ case KtErrorStatusType.notFound:
+ return 'ic_not_found.png';
+ }
+ }
+
+ String _getMessage(KtErrorStatusType type, String? message) {
+ switch (type) {
+ case KtErrorStatusType.noNetwork:
+ return 'No Network';
+ case KtErrorStatusType.loadFailed:
+ return 'Load Failed';
+ case KtErrorStatusType.nothingYet:
+ return 'Nothing here yet';
+ case KtErrorStatusType.notFound:
+ return 'Not found';
+ }
+ }
+
+ String _getSubMessage(KtErrorStatusType type, String? message) {
+ switch (type) {
+ case KtErrorStatusType.noNetwork:
+ return 'Unable to connect. Try again later.';
+ case KtErrorStatusType.loadFailed:
+ return 'We’re having trouble. Hang tight.';
+ case KtErrorStatusType.nothingYet:
+ return 'Start exploring and add something!';
+ case KtErrorStatusType.notFound:
+ return 'Sorry, we couldn\'t find anything.';
+ }
+ }
+}
diff --git a/lib/main.dart b/lib/main.dart
new file mode 100644
index 0000000..c3307d2
--- /dev/null
+++ b/lib/main.dart
@@ -0,0 +1,128 @@
+import 'package:bot_toast/bot_toast.dart';
+import 'package:firebase_core/firebase_core.dart';
+import 'package:flustars/flustars.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_easyloading/flutter_easyloading.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:get/get.dart';
+import 'package:wakelock_plus/wakelock_plus.dart';
+
+import 'kt_pages/kt_routes.dart';
+import 'kt_utils/kt_device_info_utils.dart';
+import 'kt_utils/kt_keys.dart';
+
+void main() async {
+ WidgetsFlutterBinding.ensureInitialized();
+ SystemChrome.setSystemUIOverlayStyle(
+ const SystemUiOverlayStyle(
+ statusBarColor: Colors.transparent,
+ statusBarIconBrightness: Brightness.light,
+ systemNavigationBarColor: Colors.transparent,
+ ),
+ );
+ await initSDK();
+ runApp(const MyApp());
+}
+
+initSDK() async {
+ await KtDeviceInfoUtil().init();
+ await WakelockPlus.enable();
+ EasyLoading.init();
+ EasyLoading.instance.dismissOnTap = true;
+ await SpUtil.getInstance();
+ // KtUserUtil().startOnline();
+ // await AdjustService().init();
+ // await Firebase.initializeApp();
+}
+
+final GlobalKey navigatorKey = GlobalKey();
+
+class MyApp extends StatefulWidget {
+ const MyApp({super.key});
+
+ @override
+ State createState() => _MyAppState();
+}
+
+final RouteObserver routeObserver = RouteObserver();
+
+class _MyAppState extends State with WidgetsBindingObserver {
+ DateTime? _cycleLifeTime;
+ bool _appLifecycleStateHasPaused = false;
+
+ @override
+ void initState() {
+ super.initState();
+ WidgetsBinding.instance.addObserver(this);
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ super.dispose();
+ }
+
+ // 监听生命周期状态变化
+ // @override
+ // void didChangeAppLifecycleState(AppLifecycleState state) {
+ // super.didChangeAppLifecycleState(state);
+ // if (state == AppLifecycleState.paused) {
+ // _cycleLifeTime = DateTime.now();
+ // _appLifecycleStateHasPaused = true;
+ // } else if (state == AppLifecycleState.inactive) {
+ // KtUserUtil().offLinePost();
+ // } else if (state == AppLifecycleState.resumed) {
+ // _appLifecycleStateHasPaused = false;
+ // if (!_appLifecycleStateHasPaused) {
+ // KtUserUtil().enterAppPost();
+ // KtUserUtil().reportNotify();
+ // }
+ // final now = DateTime.now();
+ // final duration = now.difference(_cycleLifeTime ?? now);
+ // if (duration.inMilliseconds > 3) {
+ // Future.delayed(const Duration(milliseconds: 1000)).then((_) {
+ // KtUserUtil().onLinePost();
+ // });
+ // }
+ // _cycleLifeTime = null;
+ // }
+ // }
+
+ @override
+ Widget build(BuildContext context) {
+ return ScreenUtilInit(
+ designSize: Size(375, 812),
+ // minTextAdapt: true,
+ builder: (context, child) {
+ return GetMaterialApp(
+ title: 'Kinetra',
+ navigatorKey: navigatorKey,
+ navigatorObservers: [routeObserver],
+ getPages: KtRoutes.routes,
+ initialRoute: KtRoutes.splash,
+ // 注册路由监听器
+ debugShowCheckedModeBanner: false,
+ locale: Get.deviceLocale,
+ // 获取设备语言
+ fallbackLocale: const Locale('en', 'US'),
+ // 默认语言
+ theme: ThemeData(
+ fontFamily: 'Inter',
+ // 设置透明导航栏
+ appBarTheme: const AppBarTheme(
+ backgroundColor: Colors.transparent,
+ elevation: 0,
+ scrolledUnderElevation: 0,
+ systemOverlayStyle: SystemUiOverlayStyle(
+ statusBarColor: Colors.transparent,
+ ),
+ ),
+ ),
+ // home: const SplashPage(),
+ builder: EasyLoading.init(builder: BotToastInit()),
+ );
+ },
+ );
+ }
+}
diff --git a/pubspec.lock b/pubspec.lock
new file mode 100644
index 0000000..603ec1b
--- /dev/null
+++ b/pubspec.lock
@@ -0,0 +1,1770 @@
+# Generated by pub
+# See https://dart.dev/tools/pub/glossary#lockfile
+packages:
+ _flutterfire_internals:
+ dependency: transitive
+ description:
+ name: _flutterfire_internals
+ sha256: "37a42d06068e2fe3deddb2da079a8c4d105f241225ba27b7122b37e9865fd8f7"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.3.35"
+ adjust_sdk:
+ dependency: "direct main"
+ description:
+ name: adjust_sdk
+ sha256: "1e1da3bd53afe1b5cde876f2aab2d572acd552d749f0309acc14a8b1e08fe8c6"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.4.1"
+ advertising_id:
+ dependency: "direct main"
+ description:
+ name: advertising_id
+ sha256: ab06ee85203ab500be85b7f45de2a75a629d8d9c453dba779276fbc4e97ad8d3
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.7.1"
+ android_id:
+ dependency: "direct main"
+ description:
+ name: android_id
+ sha256: "748ba5f93dd5c497e675d8eaa1404346ce4d1794464ea654576ff192d153b92a"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.4.0"
+ ansicolor:
+ dependency: transitive
+ description:
+ name: ansicolor
+ sha256: "50e982d500bc863e1d703448afdbf9e5a72eb48840a4f766fa361ffd6877055f"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.3"
+ app_badge_plus:
+ dependency: "direct main"
+ description:
+ name: app_badge_plus
+ sha256: cbbb03cdac77c89c1494534fc2397e7f54deb84d2f968af9f8caaecbc54e86e7
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.2.3"
+ app_links:
+ dependency: "direct main"
+ description:
+ name: app_links
+ sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.4.1"
+ app_links_linux:
+ dependency: transitive
+ description:
+ name: app_links_linux
+ sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.3"
+ app_links_platform_interface:
+ dependency: transitive
+ description:
+ name: app_links_platform_interface
+ sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.2"
+ app_links_web:
+ dependency: transitive
+ description:
+ name: app_links_web
+ sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.4"
+ app_tracking_transparency:
+ dependency: "direct main"
+ description:
+ name: app_tracking_transparency
+ sha256: "1f71f4d8402552fbf8b191d4edab301f233c1af794878b7bc56c708470ffd74c"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.6+1"
+ archive:
+ dependency: transitive
+ description:
+ name: archive
+ sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.0.7"
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.7.0"
+ async:
+ dependency: transitive
+ description:
+ name: async
+ sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.13.0"
+ badges:
+ dependency: "direct main"
+ description:
+ name: badges
+ sha256: a7b6bbd60dce418df0db3058b53f9d083c22cdb5132a052145dc267494df0b84
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.2"
+ boolean_selector:
+ dependency: transitive
+ description:
+ name: boolean_selector
+ sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.2"
+ bordered_text:
+ dependency: "direct main"
+ description:
+ name: bordered_text
+ sha256: e52c549c9d01fdf6359eee7220900eb5a5853b08aa862c8c604442918ca6b4c4
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.0"
+ bot_toast:
+ dependency: "direct main"
+ description:
+ name: bot_toast
+ sha256: "6b93030a99a98335b8827ecd83021e92e885ffc61d261d3825ffdecdd17f3bdf"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.1.3"
+ cached_network_image:
+ dependency: "direct main"
+ description:
+ name: cached_network_image
+ sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.4.1"
+ cached_network_image_platform_interface:
+ dependency: transitive
+ description:
+ name: cached_network_image_platform_interface
+ sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.1.1"
+ cached_network_image_web:
+ dependency: transitive
+ description:
+ name: cached_network_image_web
+ sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.3.1"
+ card_swiper:
+ dependency: "direct main"
+ description:
+ name: card_swiper
+ sha256: "21e52a144decbf0054e7cfed8bbe46fc89635e6c86b767eaccfe7d5aeba32528"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.0.1"
+ characters:
+ dependency: transitive
+ description:
+ name: characters
+ sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.4.0"
+ checked_yaml:
+ dependency: transitive
+ description:
+ name: checked_yaml
+ sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.4"
+ chewie:
+ dependency: "direct main"
+ description:
+ name: chewie
+ sha256: "19b93a1e60e4ba640a792208a6543f1c7d5b124d011ce0199e2f18802199d984"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.12.1"
+ cli_util:
+ dependency: transitive
+ description:
+ name: cli_util
+ sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.4.2"
+ clock:
+ dependency: transitive
+ description:
+ name: clock
+ sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.2"
+ collection:
+ dependency: transitive
+ description:
+ name: collection
+ sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.19.1"
+ common_utils:
+ dependency: transitive
+ description:
+ name: common_utils
+ sha256: c26884339b13ff99b0739e56f4b02090c84054ed9dd3a045435cd24e7b99c2c1
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.0"
+ convert:
+ dependency: transitive
+ description:
+ name: convert
+ sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.2"
+ cross_file:
+ dependency: transitive
+ description:
+ name: cross_file
+ sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.3.4+2"
+ crypto:
+ dependency: transitive
+ description:
+ name: crypto
+ sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.0.6"
+ csslib:
+ dependency: transitive
+ description:
+ name: csslib
+ sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.2"
+ cupertino_icons:
+ dependency: "direct main"
+ description:
+ name: cupertino_icons
+ sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.8"
+ dbus:
+ dependency: transitive
+ description:
+ name: dbus
+ sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.7.11"
+ decimal:
+ dependency: transitive
+ description:
+ name: decimal
+ sha256: "24a261d5d5c87e86c7651c417a5dbdf8bcd7080dd592533910e8d0505a279f21"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.3.3"
+ device_info_plus:
+ dependency: "direct main"
+ description:
+ name: device_info_plus
+ sha256: "98f28b42168cc509abc92f88518882fd58061ea372d7999aecc424345c7bff6a"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "11.5.0"
+ device_info_plus_platform_interface:
+ dependency: transitive
+ description:
+ name: device_info_plus_platform_interface
+ sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "7.0.3"
+ dio:
+ dependency: "direct main"
+ description:
+ name: dio
+ sha256: d90ee57923d1828ac14e492ca49440f65477f4bb1263575900be731a3dac66a9
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.9.0"
+ dio_web_adapter:
+ dependency: transitive
+ description:
+ name: dio_web_adapter
+ sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.1"
+ easy_debounce:
+ dependency: "direct main"
+ description:
+ name: easy_debounce
+ sha256: f082609cfb8f37defb9e37fc28bc978c6712dedf08d4c5a26f820fa10165a236
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.3"
+ easy_refresh:
+ dependency: "direct main"
+ description:
+ name: easy_refresh
+ sha256: "486e30abfcaae66c0f2c2798a10de2298eb9dc5e0bb7e1dba9328308968cae0c"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.4.0"
+ facebook_auth_desktop:
+ dependency: transitive
+ description:
+ name: facebook_auth_desktop
+ sha256: e6cc4d6f50a1d67d99e7dac7d77a40fe27122496e224cb708ae168d7d9aac0ac
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.3"
+ fake_async:
+ dependency: transitive
+ description:
+ name: fake_async
+ sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.3.3"
+ ffi:
+ dependency: transitive
+ description:
+ name: ffi
+ sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.4"
+ file:
+ dependency: transitive
+ description:
+ name: file
+ sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "7.0.1"
+ file_selector_linux:
+ dependency: transitive
+ description:
+ name: file_selector_linux
+ sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.9.3+2"
+ file_selector_macos:
+ dependency: transitive
+ description:
+ name: file_selector_macos
+ sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.9.4+4"
+ file_selector_platform_interface:
+ dependency: transitive
+ description:
+ name: file_selector_platform_interface
+ sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.6.2"
+ file_selector_windows:
+ dependency: transitive
+ description:
+ name: file_selector_windows
+ sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.9.3+4"
+ firebase_analytics:
+ dependency: "direct main"
+ description:
+ name: firebase_analytics
+ sha256: ddfcb2aadec496e3ae2c49aa77c11b416ff705c38a3faa837fcbddceb2e049fa
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "10.8.10"
+ firebase_analytics_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_analytics_platform_interface
+ sha256: "3729b74f8cf1d974a27ba70332ecb55ff5ff560edc8164a6469f4a055b429c37"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.10.8"
+ firebase_analytics_web:
+ dependency: transitive
+ description:
+ name: firebase_analytics_web
+ sha256: "019cd7eee74254d33fbd2e29229367ce33063516bf6b3258a341d89e3b0f1655"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.5.7+7"
+ firebase_core:
+ dependency: "direct main"
+ description:
+ name: firebase_core
+ sha256: "26de145bb9688a90962faec6f838247377b0b0d32cc0abecd9a4e43525fc856c"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.32.0"
+ firebase_core_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_core_platform_interface
+ sha256: "8bcfad6d7033f5ea951d15b867622a824b13812178bfec0c779b9d81de011bbb"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.4.2"
+ firebase_core_web:
+ dependency: transitive
+ description:
+ name: firebase_core_web
+ sha256: eb3afccfc452b2b2075acbe0c4b27de62dd596802b4e5e19869c1e926cbb20b3
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.24.0"
+ firebase_crashlytics:
+ dependency: "direct main"
+ description:
+ name: firebase_crashlytics
+ sha256: "9897c01efaa950d2f6da8317d12452749a74dc45f33b46390a14cfe28067f271"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.5.7"
+ firebase_crashlytics_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_crashlytics_platform_interface
+ sha256: "16a71e08fbf6e00382816e1b13397898c29a54fa0ad969c2c2a3b82a704877f0"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.6.35"
+ firebase_messaging:
+ dependency: "direct main"
+ description:
+ name: firebase_messaging
+ sha256: "980259425fa5e2afc03e533f33723335731d21a56fd255611083bceebf4373a8"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "14.7.10"
+ firebase_messaging_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_messaging_platform_interface
+ sha256: "87c4a922cb6f811cfb7a889bdbb3622702443c52a0271636cbc90d813ceac147"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.5.37"
+ firebase_messaging_web:
+ dependency: transitive
+ description:
+ name: firebase_messaging_web
+ sha256: "90dc7ed885e90a24bb0e56d661d4d2b5f84429697fd2cbb9e5890a0ca370e6f4"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.5.18"
+ firebase_performance:
+ dependency: "direct main"
+ description:
+ name: firebase_performance
+ sha256: dbcfc300755c4bb866988de20a491f0b53e1a0d14c375a2c31aa53ca82174c5b
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.9.4+7"
+ firebase_performance_platform_interface:
+ dependency: transitive
+ description:
+ name: firebase_performance_platform_interface
+ sha256: "191c9945c2ea4359cb57dc086463b2a25b0f9d8d42f66a0be4c1a7133e26ebc8"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.1.4+35"
+ firebase_performance_web:
+ dependency: transitive
+ description:
+ name: firebase_performance_web
+ sha256: "9f03a53f55697b206393366bf138e382cbd845d5021b5be6f7fc97b338da2cb5"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.1.6+7"
+ fixnum:
+ dependency: transitive
+ description:
+ name: fixnum
+ sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.1"
+ flustars:
+ dependency: "direct main"
+ description:
+ name: flustars
+ sha256: "7019ab8d68c0d4759ee122644d91a165d450b0492717f9e7e9d0ce277dcf664b"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.1"
+ flutter:
+ dependency: "direct main"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_cache_manager:
+ dependency: "direct main"
+ description:
+ name: flutter_cache_manager
+ sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.4.1"
+ flutter_card_swiper:
+ dependency: "direct main"
+ description:
+ name: flutter_card_swiper
+ sha256: "1eacbfab31b572223042e03409726553aec431abe48af48c8d591d376d070d3d"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "7.0.2"
+ flutter_easyloading:
+ dependency: "direct main"
+ description:
+ name: flutter_easyloading
+ sha256: ba21a3c883544e582f9cc455a4a0907556714e1e9cf0eababfcb600da191d17c
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.0.5"
+ flutter_facebook_auth:
+ dependency: "direct main"
+ description:
+ name: flutter_facebook_auth
+ sha256: bc455122d3ea14fd0887b1a0f74d0ead845c04bfc2e68c64d9a701367d665724
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.2.0"
+ flutter_facebook_auth_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_facebook_auth_platform_interface
+ sha256: "86630c4dbba1c20fba26ea9e59ad0d48f5ff59e7373cacd36f916160186f9ce9"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.0.0"
+ flutter_facebook_auth_web:
+ dependency: transitive
+ description:
+ name: flutter_facebook_auth_web
+ sha256: "22dca8091409309ad85b9f430fbd8f57b686276979da5195e7e97587352567ce"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.0.0"
+ flutter_image_compress:
+ dependency: "direct main"
+ description:
+ name: flutter_image_compress
+ sha256: "51d23be39efc2185e72e290042a0da41aed70b14ef97db362a6b5368d0523b27"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.0"
+ flutter_image_compress_common:
+ dependency: transitive
+ description:
+ name: flutter_image_compress_common
+ sha256: c5c5d50c15e97dd7dc72ff96bd7077b9f791932f2076c5c5b6c43f2c88607bfb
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.6"
+ flutter_image_compress_macos:
+ dependency: transitive
+ description:
+ name: flutter_image_compress_macos
+ sha256: "20019719b71b743aba0ef874ed29c50747461e5e8438980dfa5c2031898f7337"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.3"
+ flutter_image_compress_ohos:
+ dependency: transitive
+ description:
+ name: flutter_image_compress_ohos
+ sha256: e76b92bbc830ee08f5b05962fc78a532011fcd2041f620b5400a593e96da3f51
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.0.3"
+ flutter_image_compress_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_image_compress_platform_interface
+ sha256: "579cb3947fd4309103afe6442a01ca01e1e6f93dc53bb4cbd090e8ce34a41889"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.5"
+ flutter_image_compress_web:
+ dependency: transitive
+ description:
+ name: flutter_image_compress_web
+ sha256: b9b141ac7c686a2ce7bb9a98176321e1182c9074650e47bb140741a44b6f5a96
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.1.5"
+ flutter_inappwebview:
+ dependency: "direct main"
+ description:
+ name: flutter_inappwebview
+ sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.1.5"
+ flutter_inappwebview_android:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_android
+ sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.3"
+ flutter_inappwebview_internal_annotations:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_internal_annotations
+ sha256: "787171d43f8af67864740b6f04166c13190aa74a1468a1f1f1e9ee5b90c359cd"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.2.0"
+ flutter_inappwebview_ios:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_ios
+ sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.2"
+ flutter_inappwebview_macos:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_macos
+ sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.2"
+ flutter_inappwebview_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_platform_interface
+ sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.3.0+1"
+ flutter_inappwebview_web:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_web
+ sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.2"
+ flutter_inappwebview_windows:
+ dependency: transitive
+ description:
+ name: flutter_inappwebview_windows
+ sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.6.0"
+ flutter_launcher_icons:
+ dependency: "direct main"
+ description:
+ name: flutter_launcher_icons
+ sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.14.4"
+ flutter_lints:
+ dependency: "direct dev"
+ description:
+ name: flutter_lints
+ sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.0.0"
+ flutter_local_notifications:
+ dependency: "direct main"
+ description:
+ name: flutter_local_notifications
+ sha256: a9966c850de5e445331b854fa42df96a8020066d67f125a5964cbc6556643f68
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "19.4.1"
+ flutter_local_notifications_linux:
+ dependency: transitive
+ description:
+ name: flutter_local_notifications_linux
+ sha256: e3c277b2daab8e36ac5a6820536668d07e83851aeeb79c446e525a70710770a5
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.0.0"
+ flutter_local_notifications_platform_interface:
+ dependency: "direct main"
+ description:
+ name: flutter_local_notifications_platform_interface
+ sha256: "277d25d960c15674ce78ca97f57d0bae2ee401c844b6ac80fcd972a9c99d09fe"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "9.1.0"
+ flutter_local_notifications_windows:
+ dependency: transitive
+ description:
+ name: flutter_local_notifications_windows
+ sha256: ed46d7ae4ec9d19e4c8fa2badac5fe27ba87a3fe387343ce726f927af074ec98
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.2"
+ flutter_native_splash:
+ dependency: "direct main"
+ description:
+ name: flutter_native_splash
+ sha256: "8321a6d11a8d13977fa780c89de8d257cce3d841eecfb7a4cadffcc4f12d82dc"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.6"
+ flutter_plugin_android_lifecycle:
+ dependency: transitive
+ description:
+ name: flutter_plugin_android_lifecycle
+ sha256: b0694b7fb1689b0e6cc193b3f1fcac6423c4f93c74fb20b806c6b6f196db0c31
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.30"
+ flutter_screenutil:
+ dependency: "direct main"
+ description:
+ name: flutter_screenutil
+ sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.9.3"
+ flutter_secure_storage:
+ dependency: "direct main"
+ description:
+ name: flutter_secure_storage
+ sha256: "9cad52d75ebc511adfae3d447d5d13da15a55a92c9410e50f67335b6d21d16ea"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "9.2.4"
+ flutter_secure_storage_linux:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_linux
+ sha256: be76c1d24a97d0b98f8b54bce6b481a380a6590df992d0098f868ad54dc8f688
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.2.3"
+ flutter_secure_storage_macos:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_macos
+ sha256: "6c0a2795a2d1de26ae202a0d78527d163f4acbb11cde4c75c670f3a0fc064247"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.3"
+ flutter_secure_storage_platform_interface:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_platform_interface
+ sha256: cf91ad32ce5adef6fba4d736a542baca9daf3beac4db2d04be350b87f69ac4a8
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.2"
+ flutter_secure_storage_web:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_web
+ sha256: f4ebff989b4f07b2656fb16b47852c0aab9fed9b4ec1c70103368337bc1886a9
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.2.1"
+ flutter_secure_storage_windows:
+ dependency: transitive
+ description:
+ name: flutter_secure_storage_windows
+ sha256: b20b07cb5ed4ed74fc567b78a72936203f587eba460af1df11281c9326cd3709
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.2"
+ flutter_spinkit:
+ dependency: "direct main"
+ description:
+ name: flutter_spinkit
+ sha256: "77850df57c00dc218bfe96071d576a8babec24cf58b2ed121c83cca4a2fdce7f"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.2.2"
+ flutter_staggered_grid_view:
+ dependency: "direct main"
+ description:
+ name: flutter_staggered_grid_view
+ sha256: "19e7abb550c96fbfeb546b23f3ff356ee7c59a019a651f8f102a4ba9b7349395"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.7.0"
+ flutter_test:
+ dependency: "direct dev"
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ flutter_web_plugins:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ fluttertoast:
+ dependency: "direct main"
+ description:
+ name: fluttertoast
+ sha256: "25e51620424d92d3db3832464774a6143b5053f15e382d8ffbfd40b6e795dcf1"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "8.2.12"
+ get:
+ dependency: "direct main"
+ description:
+ name: get
+ sha256: c79eeb4339f1f3deffd9ec912f8a923834bec55f7b49c9e882b8fef2c139d425
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.7.2"
+ gtk:
+ dependency: transitive
+ description:
+ name: gtk
+ sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.0"
+ html:
+ dependency: transitive
+ description:
+ name: html
+ sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.15.6"
+ http:
+ dependency: transitive
+ description:
+ name: http
+ sha256: bb2ce4590bc2667c96f318d68cac1b5a7987ec819351d32b1c987239a815e007
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.5.0"
+ http_parser:
+ dependency: transitive
+ description:
+ name: http_parser
+ sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.1.2"
+ image:
+ dependency: transitive
+ description:
+ name: image
+ sha256: "4e973fcf4caae1a4be2fa0a13157aa38a8f9cb049db6529aa00b4d71abc4d928"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.5.4"
+ image_picker:
+ dependency: "direct main"
+ description:
+ name: image_picker
+ sha256: "736eb56a911cf24d1859315ad09ddec0b66104bc41a7f8c5b96b4e2620cf5041"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.2.0"
+ image_picker_android:
+ dependency: transitive
+ description:
+ name: image_picker_android
+ sha256: "28f3987ca0ec702d346eae1d90eda59603a2101b52f1e234ded62cff1d5cfa6e"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.8.13+1"
+ image_picker_for_web:
+ dependency: transitive
+ description:
+ name: image_picker_for_web
+ sha256: "40c2a6a0da15556dc0f8e38a3246064a971a9f512386c3339b89f76db87269b6"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.0"
+ image_picker_ios:
+ dependency: transitive
+ description:
+ name: image_picker_ios
+ sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.8.13"
+ image_picker_linux:
+ dependency: transitive
+ description:
+ name: image_picker_linux
+ sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.2.2"
+ image_picker_macos:
+ dependency: transitive
+ description:
+ name: image_picker_macos
+ sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.2.2"
+ image_picker_platform_interface:
+ dependency: transitive
+ description:
+ name: image_picker_platform_interface
+ sha256: "9f143b0dba3e459553209e20cc425c9801af48e6dfa4f01a0fcf927be3f41665"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.11.0"
+ image_picker_windows:
+ dependency: transitive
+ description:
+ name: image_picker_windows
+ sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.2.2"
+ in_app_purchase:
+ dependency: "direct main"
+ description:
+ name: in_app_purchase
+ sha256: "11a40f148eeb4f681a0572003e2b33432e110c90c1bbb4f9ef83b81ec0c4f737"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.2.1"
+ in_app_purchase_android:
+ dependency: "direct main"
+ description:
+ name: in_app_purchase_android
+ sha256: "5a02da1399a8faafb36d9b4acca85001b7eefa629f0eeeebf5ad0b04b9df302a"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.4.0+4"
+ in_app_purchase_platform_interface:
+ dependency: transitive
+ description:
+ name: in_app_purchase_platform_interface
+ sha256: "1d353d38251da5b9fea6635c0ebfc6bb17a2d28d0e86ea5e083bf64244f1fb4c"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.4.0"
+ in_app_purchase_storekit:
+ dependency: "direct main"
+ description:
+ name: in_app_purchase_storekit
+ sha256: "6ce1361278cacc0481508989ba419b2c9f46a2b0dc54b3fe54f5ee63c2718fef"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.3.22+1"
+ intl:
+ dependency: "direct main"
+ description:
+ name: intl
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.18.1"
+ js:
+ dependency: transitive
+ description:
+ name: js
+ sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.6.7"
+ json_annotation:
+ dependency: transitive
+ description:
+ name: json_annotation
+ sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.9.0"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "10.0.9"
+ leak_tracker_flutter_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_flutter_testing
+ sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.0.9"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.0.1"
+ lints:
+ dependency: transitive
+ description:
+ name: lints
+ sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.1.1"
+ lottie:
+ dependency: "direct main"
+ description:
+ name: lottie
+ sha256: c5fa04a80a620066c15cf19cc44773e19e9b38e989ff23ea32e5903ef1015950
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.3.1"
+ matcher:
+ dependency: transitive
+ description:
+ name: matcher
+ sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.12.17"
+ material_color_utilities:
+ dependency: transitive
+ description:
+ name: material_color_utilities
+ sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.11.1"
+ meta:
+ dependency: transitive
+ description:
+ name: meta
+ sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.16.0"
+ mime:
+ dependency: transitive
+ description:
+ name: mime
+ sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.0"
+ nested:
+ dependency: transitive
+ description:
+ name: nested
+ sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.0"
+ octo_image:
+ dependency: transitive
+ description:
+ name: octo_image
+ sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.0"
+ package_info_plus:
+ dependency: "direct main"
+ description:
+ name: package_info_plus
+ sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "8.3.1"
+ package_info_plus_platform_interface:
+ dependency: transitive
+ description:
+ name: package_info_plus_platform_interface
+ sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.2.1"
+ path:
+ dependency: transitive
+ description:
+ name: path
+ sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.9.1"
+ path_drawing:
+ dependency: transitive
+ description:
+ name: path_drawing
+ sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.0.1"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.0"
+ path_provider:
+ dependency: transitive
+ description:
+ name: path_provider
+ sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.5"
+ path_provider_android:
+ dependency: transitive
+ description:
+ name: path_provider_android
+ sha256: "993381400e94d18469750e5b9dcb8206f15bc09f9da86b9e44a9b0092a0066db"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.2.18"
+ path_provider_foundation:
+ dependency: transitive
+ description:
+ name: path_provider_foundation
+ sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.2"
+ path_provider_linux:
+ dependency: transitive
+ description:
+ name: path_provider_linux
+ sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.2.1"
+ path_provider_platform_interface:
+ dependency: transitive
+ description:
+ name: path_provider_platform_interface
+ sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.2"
+ path_provider_windows:
+ dependency: transitive
+ description:
+ name: path_provider_windows
+ sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.3.0"
+ permission_handler:
+ dependency: "direct main"
+ description:
+ name: permission_handler
+ sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "12.0.1"
+ permission_handler_android:
+ dependency: transitive
+ description:
+ name: permission_handler_android
+ sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "13.0.1"
+ permission_handler_apple:
+ dependency: transitive
+ description:
+ name: permission_handler_apple
+ sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "9.4.7"
+ permission_handler_html:
+ dependency: transitive
+ description:
+ name: permission_handler_html
+ sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.1.3+5"
+ permission_handler_platform_interface:
+ dependency: transitive
+ description:
+ name: permission_handler_platform_interface
+ sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.3.0"
+ permission_handler_windows:
+ dependency: transitive
+ description:
+ name: permission_handler_windows
+ sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.2.1"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ sha256: "1a97266a94f7350d30ae522c0af07890c70b8e62c71e8e3920d1db4d23c057d1"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "7.0.1"
+ platform:
+ dependency: transitive
+ description:
+ name: platform
+ sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.6"
+ plugin_platform_interface:
+ dependency: transitive
+ description:
+ name: plugin_platform_interface
+ sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.8"
+ posix:
+ dependency: transitive
+ description:
+ name: posix
+ sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.0.3"
+ pretty_dio_logger:
+ dependency: "direct main"
+ description:
+ name: pretty_dio_logger
+ sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.4.0"
+ provider:
+ dependency: transitive
+ description:
+ name: provider
+ sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.1.5+1"
+ pull_to_refresh:
+ dependency: "direct main"
+ description:
+ name: pull_to_refresh
+ sha256: bbadd5a931837b57739cf08736bea63167e284e71fb23b218c8c9a6e042aad12
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.0"
+ rational:
+ dependency: transitive
+ description:
+ name: rational
+ sha256: cb808fb6f1a839e6fc5f7d8cb3b0a10e1db48b3be102de73938c627f0b636336
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.2.3"
+ rxdart:
+ dependency: transitive
+ description:
+ name: rxdart
+ sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.28.0"
+ shared_preferences:
+ dependency: "direct main"
+ description:
+ name: shared_preferences
+ sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.5.3"
+ shared_preferences_android:
+ dependency: transitive
+ description:
+ name: shared_preferences_android
+ sha256: a2608114b1ffdcbc9c120eb71a0e207c71da56202852d4aab8a5e30a82269e74
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.12"
+ shared_preferences_foundation:
+ dependency: transitive
+ description:
+ name: shared_preferences_foundation
+ sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.5.4"
+ shared_preferences_linux:
+ dependency: transitive
+ description:
+ name: shared_preferences_linux
+ sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ shared_preferences_platform_interface:
+ dependency: transitive
+ description:
+ name: shared_preferences_platform_interface
+ sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ shared_preferences_web:
+ dependency: transitive
+ description:
+ name: shared_preferences_web
+ sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.3"
+ shared_preferences_windows:
+ dependency: transitive
+ description:
+ name: shared_preferences_windows
+ sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ sign_in_with_apple:
+ dependency: "direct main"
+ description:
+ name: sign_in_with_apple
+ sha256: "8bd875c8e8748272749eb6d25b896f768e7e9d60988446d543fe85a37a2392b8"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "7.0.1"
+ sign_in_with_apple_platform_interface:
+ dependency: transitive
+ description:
+ name: sign_in_with_apple_platform_interface
+ sha256: "981bca52cf3bb9c3ad7ef44aace2d543e5c468bb713fd8dda4275ff76dfa6659"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.0"
+ sign_in_with_apple_web:
+ dependency: transitive
+ description:
+ name: sign_in_with_apple_web
+ sha256: f316400827f52cafcf50d00e1a2e8a0abc534ca1264e856a81c5f06bd5b10fed
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.0.0"
+ sky_engine:
+ dependency: transitive
+ description: flutter
+ source: sdk
+ version: "0.0.0"
+ source_span:
+ dependency: transitive
+ description:
+ name: source_span
+ sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.10.1"
+ sp_util:
+ dependency: transitive
+ description:
+ name: sp_util
+ sha256: "9da43dce5de79c17a787d0626bf01538d63090ca32521200d22a232171c495dc"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.0.3"
+ sprintf:
+ dependency: transitive
+ description:
+ name: sprintf
+ sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "7.0.0"
+ sqflite:
+ dependency: transitive
+ description:
+ name: sqflite
+ sha256: e2297b1da52f127bc7a3da11439985d9b536f75070f3325e62ada69a5c585d03
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.2"
+ sqflite_android:
+ dependency: transitive
+ description:
+ name: sqflite_android
+ sha256: "2b3070c5fa881839f8b402ee4a39c1b4d561704d4ebbbcfb808a119bc2a1701b"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ sqflite_common:
+ dependency: transitive
+ description:
+ name: sqflite_common
+ sha256: "6ef422a4525ecc601db6c0a2233ff448c731307906e92cabc9ba292afaae16a6"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.5.6"
+ sqflite_darwin:
+ dependency: transitive
+ description:
+ name: sqflite_darwin
+ sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.2"
+ sqflite_platform_interface:
+ dependency: transitive
+ description:
+ name: sqflite_platform_interface
+ sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.0"
+ stack_trace:
+ dependency: transitive
+ description:
+ name: stack_trace
+ sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.12.1"
+ stream_channel:
+ dependency: transitive
+ description:
+ name: stream_channel
+ sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.4"
+ string_scanner:
+ dependency: transitive
+ description:
+ name: string_scanner
+ sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.4.1"
+ synchronized:
+ dependency: transitive
+ description:
+ name: synchronized
+ sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.4.0"
+ term_glyph:
+ dependency: transitive
+ description:
+ name: term_glyph
+ sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.2.2"
+ test_api:
+ dependency: transitive
+ description:
+ name: test_api
+ sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.7.4"
+ timezone:
+ dependency: transitive
+ description:
+ name: timezone
+ sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.10.1"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.4.0"
+ universal_io:
+ dependency: transitive
+ description:
+ name: universal_io
+ sha256: "1722b2dcc462b4b2f3ee7d188dad008b6eb4c40bbd03a3de451d82c78bba9aad"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.2.2"
+ url_launcher:
+ dependency: "direct main"
+ description:
+ name: url_launcher
+ sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.3.2"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: "69ee86740f2847b9a4ba6cffa74ed12ce500bbe2b07f3dc1e643439da60637b7"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.3.18"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.3.4"
+ url_launcher_linux:
+ dependency: transitive
+ description:
+ name: url_launcher_linux
+ sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.2.1"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.2.3"
+ url_launcher_platform_interface:
+ dependency: transitive
+ description:
+ name: url_launcher_platform_interface
+ sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.3.2"
+ url_launcher_web:
+ dependency: transitive
+ description:
+ name: url_launcher_web
+ sha256: "4bd2b7b4dc4d4d0b94e5babfffbca8eac1a126c7f3d6ecbc1a11013faa3abba2"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.1"
+ url_launcher_windows:
+ dependency: transitive
+ description:
+ name: url_launcher_windows
+ sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.4"
+ uuid:
+ dependency: transitive
+ description:
+ name: uuid
+ sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.5.1"
+ vector_math:
+ dependency: transitive
+ description:
+ name: vector_math
+ sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.4"
+ video_player:
+ dependency: "direct main"
+ description:
+ name: video_player
+ sha256: "0d55b1f1a31e5ad4c4967bfaa8ade0240b07d20ee4af1dfef5f531056512961a"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.10.0"
+ video_player_android:
+ dependency: transitive
+ description:
+ name: video_player_android
+ sha256: "59e5a457ddcc1688f39e9aef0efb62aa845cf0cbbac47e44ac9730dc079a2385"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.8.13"
+ video_player_avfoundation:
+ dependency: transitive
+ description:
+ name: video_player_avfoundation
+ sha256: f9a780aac57802b2892f93787e5ea53b5f43cc57dc107bee9436458365be71cd
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.8.4"
+ video_player_platform_interface:
+ dependency: transitive
+ description:
+ name: video_player_platform_interface
+ sha256: cf2a1d29a284db648fd66cbd18aacc157f9862d77d2cc790f6f9678a46c1db5a
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.4.0"
+ video_player_web:
+ dependency: transitive
+ description:
+ name: video_player_web
+ sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.4.0"
+ visibility_detector:
+ dependency: "direct main"
+ description:
+ name: visibility_detector
+ sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "0.4.0+2"
+ vm_service:
+ dependency: transitive
+ description:
+ name: vm_service
+ sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "15.0.0"
+ wakelock_plus:
+ dependency: "direct main"
+ description:
+ name: wakelock_plus
+ sha256: a474e314c3e8fb5adef1f9ae2d247e57467ad557fa7483a2b895bc1b421c5678
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.3.2"
+ wakelock_plus_platform_interface:
+ dependency: transitive
+ description:
+ name: wakelock_plus_platform_interface
+ sha256: e10444072e50dbc4999d7316fd303f7ea53d31c824aa5eb05d7ccbdd98985207
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.2.3"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.1"
+ webview_flutter:
+ dependency: "direct main"
+ description:
+ name: webview_flutter
+ sha256: c3e4fe614b1c814950ad07186007eff2f2e5dd2935eba7b9a9a1af8e5885f1ba
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.13.0"
+ webview_flutter_android:
+ dependency: transitive
+ description:
+ name: webview_flutter_android
+ sha256: "9a25f6b4313978ba1c2cda03a242eea17848174912cfb4d2d8ee84a556f248e3"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "4.10.1"
+ webview_flutter_platform_interface:
+ dependency: transitive
+ description:
+ name: webview_flutter_platform_interface
+ sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.14.0"
+ webview_flutter_wkwebview:
+ dependency: transitive
+ description:
+ name: webview_flutter_wkwebview
+ sha256: fb46db8216131a3e55bcf44040ca808423539bc6732e7ed34fb6d8044e3d512f
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.23.0"
+ win32:
+ dependency: transitive
+ description:
+ name: win32
+ sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "5.14.0"
+ win32_registry:
+ dependency: transitive
+ description:
+ name: win32_registry
+ sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "2.1.0"
+ xdg_directories:
+ dependency: transitive
+ description:
+ name: xdg_directories
+ sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "1.1.0"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025"
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "6.6.1"
+ yaml:
+ dependency: transitive
+ description:
+ name: yaml
+ sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
+ url: "https://pub.flutter-io.cn"
+ source: hosted
+ version: "3.1.3"
+sdks:
+ dart: ">=3.8.1 <4.0.0"
+ flutter: ">=3.29.0"
diff --git a/pubspec.yaml b/pubspec.yaml
new file mode 100644
index 0000000..7c92bc2
--- /dev/null
+++ b/pubspec.yaml
@@ -0,0 +1,132 @@
+name: flutter_kinetra
+description: "A new Flutter project."
+publish_to: 'none' # Remove this line if you wish to publish to pub.dev
+
+version: 1.0.1+1
+
+environment:
+ sdk: ^3.8.1
+
+dependencies:
+ flutter:
+ sdk: flutter
+
+ # The following adds the Cupertino Icons font to your application.
+ # Use with the CupertinoIcons class for iOS style icons.
+ cupertino_icons: ^1.0.8
+ flutter_screenutil: ^5.9.3
+ dio: ^5.8.0+1
+ chewie: ^1.7.5
+ video_player: ^2.10.0
+ card_swiper: ^3.0.1
+ cached_network_image: ^3.4.1
+ get: ^4.7.2
+ intl: ^0.18.1
+ webview_flutter: ^4.13.0
+ shared_preferences: ^2.5.3
+ flutter_cache_manager: ^3.3.2
+ flutter_native_splash: ^2.4.6
+ flutter_launcher_icons: ^0.14.4
+ flutter_card_swiper: ^7.0.2
+ fluttertoast: ^8.2.11
+ device_info_plus: ^11.5.0
+ package_info_plus: ^8.3.0
+ pretty_dio_logger: ^1.4.0
+ flutter_staggered_grid_view: ^0.7.0
+ flutter_secure_storage: ^9.2.4
+ pull_to_refresh: ^2.0.0
+ flutter_easyloading: ^3.0.5
+ easy_debounce: ^2.0.3
+ wakelock_plus: ^1.3.2
+ in_app_purchase: 3.2.1
+ in_app_purchase_storekit: ^0.3.22+1
+ in_app_purchase_android: ^0.4.0+2
+ sign_in_with_apple: ^7.0.1
+ flutter_facebook_auth: 6.2.0
+ flutter_inappwebview: ^6.1.5
+ flutter_image_compress: ^2.4.0
+ image_picker: ^1.1.2
+ badges: ^3.1.2
+ permission_handler: ^12.0.1
+ adjust_sdk: 5.4.1
+ app_links: ^6.4.0
+ app_tracking_transparency: ^2.0.6+1
+ advertising_id: ^2.7.1
+ firebase_core: 2.32.0
+ firebase_crashlytics: 3.5.7
+ firebase_messaging: 14.7.10
+ firebase_analytics: 10.8.10
+ firebase_performance: 0.9.4+7
+ flutter_local_notifications: ^19.1.0
+ flutter_local_notifications_platform_interface: ^9.0.0
+ app_badge_plus: ^1.2.3
+ url_launcher: ^6.3.1
+ visibility_detector: ^0.4.0+2
+ android_id: ^0.4.0
+ bordered_text: ^2.0.0
+ flustars: ^2.0.1
+ flutter_spinkit: ^5.2.1
+ bot_toast: ^4.1.3
+ lottie: ^3.3.1
+ easy_refresh: ^3.4.0
+
+
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+
+ # The "flutter_lints" package below contains a set of recommended lints to
+ # encourage good coding practices. The lint set provided by the package is
+ # activated in the `analysis_options.yaml` file located at the root of your
+ # package. See that file for information about deactivating specific lint
+ # rules and activating additional ones.
+ flutter_lints: ^5.0.0
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter packages.
+flutter:
+
+ # The following line ensures that the Material Icons font is
+ # included with your application, so that you can use the icons in
+ # the material Icons class.
+ uses-material-design: true
+
+ # To add assets to your application, add an assets section, like this:
+ assets:
+ - assets/
+
+ # 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: AaHouDiHei
+# fonts:
+# - asset: assets/fonts/AaHouDiHei-Regular.ttf
+# - family: MontserratAlternates
+# fonts:
+# - asset: assets/fonts/MontserratAlternates-Italic.ttf
+# - asset: assets/fonts/MontserratAlternates-MediumItalic.ttf
+# weight: 500
+# - asset: assets/fonts/MontserratAlternates-SemiBoldItalic.ttf
+# weight: 600
+# - asset: assets/fonts/MontserratAlternates-BlackItalic.ttf
+# weight: 800
+# - family: Inter
+# fonts:
+# - asset: assets/fonts/Inter-Regular-9.otf
+# weight: 400
+# - asset: assets/fonts/Inter-Medium-8.otf
+# weight: 500
+# - asset: assets/fonts/Inter-SemiBold-10.otf
+# weight: 600
+# - asset: assets/fonts/Inter-Bold-4.otf
+# weight: 700
+
+ # For details regarding fonts from package dependencies,
+ # see https://flutter.dev/to/font-from-package
+
diff --git a/test/widget_test.dart b/test/widget_test.dart
new file mode 100644
index 0000000..587d82e
--- /dev/null
+++ b/test/widget_test.dart
@@ -0,0 +1,30 @@
+// This is a basic Flutter widget test.
+//
+// To perform an interaction with a widget in your test, use the WidgetTester
+// utility in the flutter_test package. For example, you can send tap and scroll
+// gestures. You can also use WidgetTester to find child kt_widgets in the widget
+// tree, read text, and verify that the values of widget properties are correct.
+
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+import 'package:flutter_kinetra/main.dart';
+
+void main() {
+ testWidgets('Counter increments smoke test', (WidgetTester tester) async {
+ // Build our app and trigger a frame.
+ await tester.pumpWidget(const MyApp());
+
+ // Verify that our counter starts at 0.
+ expect(find.text('0'), findsOneWidget);
+ expect(find.text('1'), findsNothing);
+
+ // Tap the '+' icon and trigger a frame.
+ await tester.tap(find.byIcon(Icons.add));
+ await tester.pump();
+
+ // Verify that our counter has incremented.
+ expect(find.text('0'), findsNothing);
+ expect(find.text('1'), findsOneWidget);
+ });
+}