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); + }); +}