diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 568bcbd..0000000 --- a/.gitignore +++ /dev/null @@ -1,47 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release -.fvm/ \ No newline at end of file diff --git a/.metadata b/.metadata deleted file mode 100644 index 77d4f23..0000000 --- a/.metadata +++ /dev/null @@ -1,36 +0,0 @@ -# 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. - -version: - revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - channel: stable - -project_type: app - -# Tracks metadata for the flutter migrate command -migration: - platforms: - - platform: root - create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - - platform: linux - create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - - platform: macos - create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - - platform: windows - create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268 - - # 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/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index d234201..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,53 +0,0 @@ -## v1.0.7 -* 首页任务增加分类 -* 增加国际化相关配置 -* 登录页状态栏适配 - -## v1.0.6 -* 支持切换账号功能 -* 登录页青龙图标随颜色主题变换 -* apk大小减少2/3,只支持arm架构,不再支持x86 - -## v1.0.5 -* 优化配置文件编辑功能 -* 优化文本选择样式 -* 增加页面错误toast -* 修改iOS端app icon - -## 1.0.4 -* 增加主题切换功能,各种颜色主题随意切换 -* 修改无法停止任务的bug -* 修改脚本管理页面json解析失败的bug -* 修改变更配置文件没有及时刷新UI的bug -* 增加版本更新提醒功能(需要手机能联通github) -* 登录页面长按青龙logo可以呼出网络请求日志,再次长按可关闭 -* 打开系统最近任务时展示APP的名称 -* 优化使用体验 - -## 1.0.3 - -* 解决2.10.12及以下版本无法登录的问题 -* 适配最新版qinglong 相关接口字段 -* 其他页面排版优化 - -## 1.0.2 - -* 支持修改用户名密码(仅限使用用户名密码登录用户) -* 支持脚本的编辑删除 -* 支持client_id登录之后只启用部分模块 -* 支持两步验证 - -## 1.0.1 - -* 增加任务详情页 -* 增加环境变量详情页 -* 环境变量列表使用体验优化 -* 部分页面进入卡顿优化 -* 扩大任务的搜索范围 -* 优化暗黑主题 -* 支持client_id登录 -* 修改bug - -## 1.0.0 - -* 完成基础功能 diff --git a/analysis_options.yaml b/analysis_options.yaml deleted file mode 100644 index 61b6c4d..0000000 --- a/analysis_options.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# 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-lang.github.io/linter/lints/index.html. - # - # 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 deleted file mode 100644 index 6f56801..0000000 --- a/android/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties -**/*.keystore -**/*.jks diff --git a/android/app/build.gradle b/android/app/build.gradle deleted file mode 100644 index d9436ff..0000000 --- a/android/app/build.gradle +++ /dev/null @@ -1,82 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion flutter.compileSdkVersion - - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } - - kotlinOptions { - jvmTarget = '1.8' - } - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "work.master.qinglongapp" - minSdkVersion 21 - targetSdkVersion flutter.targetSdkVersion - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - ndk { - abiFilters 'armeabi-v7a', 'arm64-v8a' - } - } - signingConfigs { - - release { - storeFile file("qinglong.keystore") - storePassword "jiangyuesong" - keyAlias "jiangyuesong" - keyPassword "jiangyuesong" - - // Optional, specify signing versions used - v1SigningEnabled true - v2SigningEnabled true - } - } - buildTypes { - release { - signingConfig signingConfigs.release - } - } - -} - -flutter { - source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index dab2770..0000000 --- a/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 59d0476..0000000 --- a/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/android/app/src/main/kotlin/work/master/qinglong_app/MainActivity.kt b/android/app/src/main/kotlin/work/master/qinglong_app/MainActivity.kt deleted file mode 100644 index 502b907..0000000 --- a/android/app/src/main/kotlin/work/master/qinglong_app/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package work.master.qinglong_app - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/android/app/src/main/kotlin/work/master/qinglongapp/MainActivity.kt b/android/app/src/main/kotlin/work/master/qinglongapp/MainActivity.kt deleted file mode 100644 index 15b437b..0000000 --- a/android/app/src/main/kotlin/work/master/qinglongapp/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package work.master.qinglongapp - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/android/app/src/main/res/drawable-hdpi/splash.png b/android/app/src/main/res/drawable-hdpi/splash.png deleted file mode 100644 index 07112ee..0000000 Binary files a/android/app/src/main/res/drawable-hdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-mdpi/splash.png b/android/app/src/main/res/drawable-mdpi/splash.png deleted file mode 100644 index e7b83a2..0000000 Binary files a/android/app/src/main/res/drawable-mdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-night-v21/background.png b/android/app/src/main/res/drawable-night-v21/background.png deleted file mode 100644 index 1b5df34..0000000 Binary files a/android/app/src/main/res/drawable-night-v21/background.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-night-v21/launch_background.xml b/android/app/src/main/res/drawable-night-v21/launch_background.xml deleted file mode 100644 index 3fe6b2e..0000000 --- a/android/app/src/main/res/drawable-night-v21/launch_background.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/drawable-night/background.png b/android/app/src/main/res/drawable-night/background.png deleted file mode 100644 index 1b5df34..0000000 Binary files a/android/app/src/main/res/drawable-night/background.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-night/launch_background.xml b/android/app/src/main/res/drawable-night/launch_background.xml deleted file mode 100644 index 3fe6b2e..0000000 --- a/android/app/src/main/res/drawable-night/launch_background.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/drawable-v21/background.png b/android/app/src/main/res/drawable-v21/background.png deleted file mode 100644 index e29b3b5..0000000 Binary files a/android/app/src/main/res/drawable-v21/background.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index 3fe6b2e..0000000 --- a/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/drawable-xhdpi/splash.png b/android/app/src/main/res/drawable-xhdpi/splash.png deleted file mode 100644 index 2e1e8b4..0000000 Binary files a/android/app/src/main/res/drawable-xhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxhdpi/splash.png b/android/app/src/main/res/drawable-xxhdpi/splash.png deleted file mode 100644 index f7f2b26..0000000 Binary files a/android/app/src/main/res/drawable-xxhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/splash.png b/android/app/src/main/res/drawable-xxxhdpi/splash.png deleted file mode 100644 index 0b1ae4d..0000000 Binary files a/android/app/src/main/res/drawable-xxxhdpi/splash.png and /dev/null differ diff --git a/android/app/src/main/res/drawable/background.png b/android/app/src/main/res/drawable/background.png deleted file mode 100644 index e29b3b5..0000000 Binary files a/android/app/src/main/res/drawable/background.png and /dev/null differ diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 3fe6b2e..0000000 --- a/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index 17e4046..0000000 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null 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 deleted file mode 100644 index 3afa7d4..0000000 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null 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 deleted file mode 100644 index 8a7cdd7..0000000 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null 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 deleted file mode 100644 index 0b1ae4d..0000000 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null 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 deleted file mode 100644 index 4f74dc1..0000000 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/android/app/src/main/res/values-night-v31/styles.xml b/android/app/src/main/res/values-night-v31/styles.xml deleted file mode 100644 index 2c37995..0000000 --- a/android/app/src/main/res/values-night-v31/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 174b2c5..0000000 --- a/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/values-v31/styles.xml b/android/app/src/main/res/values-v31/styles.xml deleted file mode 100644 index 37aab1f..0000000 --- a/android/app/src/main/res/values-v31/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 4e3029c..0000000 --- a/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index dab2770..0000000 --- a/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/android/build.gradle b/android/build.gradle deleted file mode 100644 index 4256f91..0000000 --- a/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.6.10' - repositories { - google() - mavenCentral() - } - - dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - mavenCentral() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/android/gradle.properties b/android/gradle.properties deleted file mode 100644 index 94adc3a..0000000 --- a/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index bc6a58a..0000000 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 23 08:50:38 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/android/settings.gradle b/android/settings.gradle deleted file mode 100644 index 44e62bc..0000000 --- a/android/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -include ':app' - -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() - -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/apk/app-release-v1.0.6.apk b/apk/app-release-v1.0.6.apk deleted file mode 100644 index 627f09a..0000000 Binary files a/apk/app-release-v1.0.6.apk and /dev/null differ diff --git a/apk/app-release-v1.0.8.apk b/apk/app-release-v1.0.8.apk deleted file mode 100644 index 077d4e0..0000000 Binary files a/apk/app-release-v1.0.8.apk and /dev/null differ diff --git a/assets/images/add_btn_svip.png b/assets/images/add_btn_svip.png deleted file mode 100644 index fef251c..0000000 Binary files a/assets/images/add_btn_svip.png and /dev/null differ diff --git a/assets/images/dark.png b/assets/images/dark.png deleted file mode 100644 index f48d0dd..0000000 Binary files a/assets/images/dark.png and /dev/null differ diff --git a/assets/images/faceid.png b/assets/images/faceid.png deleted file mode 100644 index 6485236..0000000 Binary files a/assets/images/faceid.png and /dev/null differ diff --git a/assets/images/figure.png b/assets/images/figure.png deleted file mode 100644 index a44cdb1..0000000 Binary files a/assets/images/figure.png and /dev/null differ diff --git a/assets/images/icon_a.png b/assets/images/icon_a.png deleted file mode 100644 index 6f678dd..0000000 Binary files a/assets/images/icon_a.png and /dev/null differ diff --git a/assets/images/icon_about.png b/assets/images/icon_about.png deleted file mode 100644 index ce3d4a5..0000000 Binary files a/assets/images/icon_about.png and /dev/null differ diff --git a/assets/images/icon_add_file.png b/assets/images/icon_add_file.png deleted file mode 100644 index 94505fc..0000000 Binary files a/assets/images/icon_add_file.png and /dev/null differ diff --git a/assets/images/icon_app_set.png b/assets/images/icon_app_set.png deleted file mode 100644 index 2c70174..0000000 Binary files a/assets/images/icon_app_set.png and /dev/null differ diff --git a/assets/images/icon_b.png b/assets/images/icon_b.png deleted file mode 100644 index e8401eb..0000000 Binary files a/assets/images/icon_b.png and /dev/null differ diff --git a/assets/images/icon_check.png b/assets/images/icon_check.png deleted file mode 100644 index bd07524..0000000 Binary files a/assets/images/icon_check.png and /dev/null differ diff --git a/assets/images/icon_cron.png b/assets/images/icon_cron.png deleted file mode 100644 index a03802f..0000000 Binary files a/assets/images/icon_cron.png and /dev/null differ diff --git a/assets/images/icon_cron_checked.png b/assets/images/icon_cron_checked.png deleted file mode 100644 index 705f9b3..0000000 Binary files a/assets/images/icon_cron_checked.png and /dev/null differ diff --git a/assets/images/icon_d.png b/assets/images/icon_d.png deleted file mode 100644 index 3c2af27..0000000 Binary files a/assets/images/icon_d.png and /dev/null differ diff --git a/assets/images/icon_default_user.png b/assets/images/icon_default_user.png deleted file mode 100644 index 09a62ac..0000000 Binary files a/assets/images/icon_default_user.png and /dev/null differ diff --git a/assets/images/icon_disabled.png b/assets/images/icon_disabled.png deleted file mode 100644 index 2e06765..0000000 Binary files a/assets/images/icon_disabled.png and /dev/null differ diff --git a/assets/images/icon_enable.png b/assets/images/icon_enable.png deleted file mode 100644 index 2ac6a5b..0000000 Binary files a/assets/images/icon_enable.png and /dev/null differ diff --git a/assets/images/icon_env.png b/assets/images/icon_env.png deleted file mode 100644 index 66e1dbe..0000000 Binary files a/assets/images/icon_env.png and /dev/null differ diff --git a/assets/images/icon_env_checked.png b/assets/images/icon_env_checked.png deleted file mode 100644 index 1ece568..0000000 Binary files a/assets/images/icon_env_checked.png and /dev/null differ diff --git a/assets/images/icon_fail.png b/assets/images/icon_fail.png deleted file mode 100644 index e8c79ff..0000000 Binary files a/assets/images/icon_fail.png and /dev/null differ diff --git a/assets/images/icon_file.png b/assets/images/icon_file.png deleted file mode 100644 index ad94f24..0000000 Binary files a/assets/images/icon_file.png and /dev/null differ diff --git a/assets/images/icon_file_checked.png b/assets/images/icon_file_checked.png deleted file mode 100644 index 54f39de..0000000 Binary files a/assets/images/icon_file_checked.png and /dev/null differ diff --git a/assets/images/icon_history.png b/assets/images/icon_history.png deleted file mode 100644 index c89227a..0000000 Binary files a/assets/images/icon_history.png and /dev/null differ diff --git a/assets/images/icon_idle.png b/assets/images/icon_idle.png deleted file mode 100644 index 3a812b3..0000000 Binary files a/assets/images/icon_idle.png and /dev/null differ diff --git a/assets/images/icon_install_fail.png b/assets/images/icon_install_fail.png deleted file mode 100644 index 07b75e8..0000000 Binary files a/assets/images/icon_install_fail.png and /dev/null differ diff --git a/assets/images/icon_install_success.png b/assets/images/icon_install_success.png deleted file mode 100644 index 4beab6a..0000000 Binary files a/assets/images/icon_install_success.png and /dev/null differ diff --git a/assets/images/icon_login_icon.png b/assets/images/icon_login_icon.png deleted file mode 100644 index 9740da1..0000000 Binary files a/assets/images/icon_login_icon.png and /dev/null differ diff --git a/assets/images/icon_other.png b/assets/images/icon_other.png deleted file mode 100644 index 94c7b06..0000000 Binary files a/assets/images/icon_other.png and /dev/null differ diff --git a/assets/images/icon_other_bg.png b/assets/images/icon_other_bg.png deleted file mode 100644 index 4f92b04..0000000 Binary files a/assets/images/icon_other_bg.png and /dev/null differ diff --git a/assets/images/icon_other_checked.png b/assets/images/icon_other_checked.png deleted file mode 100644 index 58282f7..0000000 Binary files a/assets/images/icon_other_checked.png and /dev/null differ diff --git a/assets/images/icon_right.png b/assets/images/icon_right.png deleted file mode 100644 index d2482dd..0000000 Binary files a/assets/images/icon_right.png and /dev/null differ diff --git a/assets/images/icon_running.png b/assets/images/icon_running.png deleted file mode 100644 index 3b26804..0000000 Binary files a/assets/images/icon_running.png and /dev/null differ diff --git a/assets/images/icon_s.png b/assets/images/icon_s.png deleted file mode 100644 index b9b5ff0..0000000 Binary files a/assets/images/icon_s.png and /dev/null differ diff --git a/assets/images/icon_safety.png b/assets/images/icon_safety.png deleted file mode 100644 index 96a115e..0000000 Binary files a/assets/images/icon_safety.png and /dev/null differ diff --git a/assets/images/icon_search.png b/assets/images/icon_search.png deleted file mode 100644 index f4a9d00..0000000 Binary files a/assets/images/icon_search.png and /dev/null differ diff --git a/assets/images/icon_setting.png b/assets/images/icon_setting.png deleted file mode 100644 index bea3c72..0000000 Binary files a/assets/images/icon_setting.png and /dev/null differ diff --git a/assets/images/icon_subsctibe.png b/assets/images/icon_subsctibe.png deleted file mode 100644 index d8fe88b..0000000 Binary files a/assets/images/icon_subsctibe.png and /dev/null differ diff --git a/assets/images/icon_success.png b/assets/images/icon_success.png deleted file mode 100644 index f3b9989..0000000 Binary files a/assets/images/icon_success.png and /dev/null differ diff --git a/assets/images/icon_task_disable.png b/assets/images/icon_task_disable.png deleted file mode 100644 index cf64717..0000000 Binary files a/assets/images/icon_task_disable.png and /dev/null differ diff --git a/assets/images/icon_task_log.png b/assets/images/icon_task_log.png deleted file mode 100644 index 9b83895..0000000 Binary files a/assets/images/icon_task_log.png and /dev/null differ diff --git a/assets/images/icon_uncheck.png b/assets/images/icon_uncheck.png deleted file mode 100644 index 028c457..0000000 Binary files a/assets/images/icon_uncheck.png and /dev/null differ diff --git a/assets/images/icon_vip_bg.png b/assets/images/icon_vip_bg.png deleted file mode 100644 index 7173c03..0000000 Binary files a/assets/images/icon_vip_bg.png and /dev/null differ diff --git a/assets/images/icon_vip_bg_check.png b/assets/images/icon_vip_bg_check.png deleted file mode 100644 index e562e12..0000000 Binary files a/assets/images/icon_vip_bg_check.png and /dev/null differ diff --git a/assets/images/js.png b/assets/images/js.png deleted file mode 100644 index 91d1188..0000000 Binary files a/assets/images/js.png and /dev/null differ diff --git a/assets/images/json.png b/assets/images/json.png deleted file mode 100644 index f39a8c4..0000000 Binary files a/assets/images/json.png and /dev/null differ diff --git a/assets/images/light.png b/assets/images/light.png deleted file mode 100644 index 669384e..0000000 Binary files a/assets/images/light.png and /dev/null differ diff --git a/assets/images/loading.png b/assets/images/loading.png deleted file mode 100644 index 9a9d0d5..0000000 Binary files a/assets/images/loading.png and /dev/null differ diff --git a/assets/images/login_bg.png b/assets/images/login_bg.png deleted file mode 100644 index 20f1d39..0000000 Binary files a/assets/images/login_bg.png and /dev/null differ diff --git a/assets/images/login_tip.png b/assets/images/login_tip.png deleted file mode 100644 index 4ca3867..0000000 Binary files a/assets/images/login_tip.png and /dev/null differ diff --git a/assets/images/normal.png b/assets/images/normal.png deleted file mode 100644 index 52ac4b5..0000000 Binary files a/assets/images/normal.png and /dev/null differ diff --git a/assets/images/other.png b/assets/images/other.png deleted file mode 100644 index f8cffc3..0000000 Binary files a/assets/images/other.png and /dev/null differ diff --git a/assets/images/py.png b/assets/images/py.png deleted file mode 100644 index 2213506..0000000 Binary files a/assets/images/py.png and /dev/null differ diff --git a/assets/images/ql.png b/assets/images/ql.png deleted file mode 100644 index 09bc684..0000000 Binary files a/assets/images/ql.png and /dev/null differ diff --git a/assets/images/ql_splash.png b/assets/images/ql_splash.png deleted file mode 100644 index c508382..0000000 Binary files a/assets/images/ql_splash.png and /dev/null differ diff --git a/assets/images/ql_white.png b/assets/images/ql_white.png deleted file mode 100644 index 09bc684..0000000 Binary files a/assets/images/ql_white.png and /dev/null differ diff --git a/assets/images/shell.png b/assets/images/shell.png deleted file mode 100644 index 9563d70..0000000 Binary files a/assets/images/shell.png and /dev/null differ diff --git a/assets/images/svip.png b/assets/images/svip.png deleted file mode 100644 index 2590eb2..0000000 Binary files a/assets/images/svip.png and /dev/null differ diff --git a/assets/images/svip_logo.png b/assets/images/svip_logo.png deleted file mode 100644 index bfb314f..0000000 Binary files a/assets/images/svip_logo.png and /dev/null differ diff --git a/assets/images/ts.png b/assets/images/ts.png deleted file mode 100644 index 0bc3036..0000000 Binary files a/assets/images/ts.png and /dev/null differ diff --git a/assets/images/update_bg_app_top.png b/assets/images/update_bg_app_top.png deleted file mode 100644 index d97da82..0000000 Binary files a/assets/images/update_bg_app_top.png and /dev/null differ diff --git a/assets/images/update_ic_close.png b/assets/images/update_ic_close.png deleted file mode 100644 index 29e55e9..0000000 Binary files a/assets/images/update_ic_close.png and /dev/null differ diff --git a/assets/images/vip.png b/assets/images/vip.png deleted file mode 100644 index e2e98ff..0000000 Binary files a/assets/images/vip.png and /dev/null differ diff --git a/assets/images/vip_logo.png b/assets/images/vip_logo.png deleted file mode 100644 index d8c89f9..0000000 Binary files a/assets/images/vip_logo.png and /dev/null differ diff --git a/lib/base/base_state_widget.dart b/lib/base/base_state_widget.dart deleted file mode 100644 index d005ff6..0000000 --- a/lib/base/base_state_widget.dart +++ /dev/null @@ -1,83 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/ui/lazy_load_state.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'base_viewmodel.dart'; - -class BaseStateWidget extends ConsumerStatefulWidget { - final Widget Function(WidgetRef context, T value, Widget? child) builder; - final ProviderBase model; - final Widget? child; - final Function(T)? onReady; - final bool lazyLoad; - - const BaseStateWidget({ - Key? key, - required this.builder, - required this.model, - this.child, - this.onReady, - this.lazyLoad = false, - }) : super(key: key); - - @override - _BaseStateWidgetState createState() => _BaseStateWidgetState(); -} - -class _BaseStateWidgetState - extends ConsumerState> - with LazyLoadState> { - @override - Widget build(BuildContext context) { - var viewModel = ref.watch(widget.model); - if (viewModel.failedToast != null) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - (viewModel.failedToast ?? "").toast(); - viewModel.clearToast(); - }); - } - if (viewModel.currentState == PageState.CONTENT) { - return widget.builder(ref, viewModel, widget.child); - } - - if (viewModel.currentState == PageState.LOADING) { - return Container( - alignment: Alignment.center, - child: const CupertinoActivityIndicator(), - ); - } - - if (viewModel.currentState == PageState.FAILED) { - return Container( - alignment: Alignment.center, - child: Text(viewModel.failReason ?? ""), - ); - } - - if (viewModel.currentState == PageState.EMPTY) { - return Container( - alignment: Alignment.center, - child: const Text("暂无数据"), - ); - } - - return Container(); - } - - @override - void onLazyLoad() { - if (widget.onReady != null && widget.lazyLoad) { - widget.onReady!(ref.read(widget.model)); - } - } - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - if (widget.onReady != null && !widget.lazyLoad) { - widget.onReady!(ref.read(widget.model)); - } - }); - } -} diff --git a/lib/base/base_viewmodel.dart b/lib/base/base_viewmodel.dart deleted file mode 100644 index d8c8642..0000000 --- a/lib/base/base_viewmodel.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter/cupertino.dart'; - -class ViewModel extends ChangeNotifier {} - -class BaseViewModel extends ViewModel { - PageState currentState = PageState.START; - String? failReason; - String? failedToast; - - void loading({bool notify = false}) { - failReason = null; - failedToast = null; - currentState = PageState.LOADING; - if (notify) { - notifyListeners(); - } - } - - void success({bool notify = true}) { - failReason = null; - failedToast = null; - currentState = PageState.CONTENT; - if (notify) { - notifyListeners(); - } - } - - void failed(String? reason, {bool notify = false}) { - currentState = PageState.FAILED; - failReason = reason; - failedToast = null; - if (notify) { - notifyListeners(); - } - } - - void failToast(String? reason, {bool notify = false}) { - currentState = PageState.CONTENT; - failedToast = reason; - failReason = reason; - if (notify) { - notifyListeners(); - } - } - - void clearToast() { - failedToast = null; - } - - void empty({bool notify = false}) { - failReason = null; - failedToast = null; - currentState = PageState.EMPTY; - if (notify) { - notifyListeners(); - } - } -} - -enum PageState { - START, - LOADING, - EMPTY, - CONTENT, - FAILED, -} diff --git a/lib/base/http/api.dart b/lib/base/http/api.dart deleted file mode 100644 index d504dcc..0000000 --- a/lib/base/http/api.dart +++ /dev/null @@ -1,466 +0,0 @@ -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/http/url.dart'; -import 'package:qinglong_app/main.dart'; -import 'package:qinglong_app/module/config/config_bean.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/module/home/system_bean.dart'; -import 'package:qinglong_app/module/login/login_bean.dart'; -import 'package:qinglong_app/module/login/user_bean.dart'; -import 'package:qinglong_app/module/others/dependencies/dependency_bean.dart'; -import 'package:qinglong_app/module/others/login_log/login_log_bean.dart'; -import 'package:qinglong_app/module/others/scripts/script_bean.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_bean.dart'; -import 'package:qinglong_app/module/others/task_log/task_log_bean.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/utils/utils.dart'; - -class Api { - static Future> system() async { - return await Http.get( - Url.system, - {}, - ); - } - - static Future> login( - String userName, - String passWord, - ) async { - return await Http.post( - Url.login, - { - "username": userName, - "password": passWord, - }, - ); - } - - static Future> loginOld( - String userName, - String passWord, - ) async { - return await Http.post( - Url.loginOld, - { - "username": userName, - "password": passWord, - }, - ); - } - - static Future> loginTwo( - String userName, - String passWord, - String code, - ) async { - return await Http.put( - Url.loginTwo, - { - "username": userName, - "password": passWord, - "code": code, - }, - ); - } - - static Future> loginByClientId( - String id, - String secret, - ) async { - return await Http.get( - Url.loginByClientId, - { - "client_id": id, - "client_secret": secret, - }, - ); - } - - static Future> user() async { - return await Http.get( - Url.user, - null, - ); - } - - static Future>> crons() async { - return await Http.get>( - Url.tasks, - {"searchValue": ""}, - ); - } - - static Future> startTasks(List crons) async { - return await Http.put( - Url.runTasks, - crons, - ); - } - - static Future> stopTasks(List crons) async { - return await Http.put( - Url.stopTasks, - crons, - ); - } - - static Future> updatePassword(String name, String password) async { - return await Http.put( - Url.updatePassword, - { - "username": name, - "password": password, - }, - ); - } - - static Future> inTimeLog(String cron) async { - return await Http.get( - Url.intimeLog(cron), - null, - ); - } - - static Future> addTask( - String name, - String command, - String cron, { - int? id, - String? nId, - }) async { - var data = {"name": name, "command": command, "schedule": cron}; - - if (id != null || nId != null) { - if (id != null) { - data["id"] = id; - } else if (nId != null) { - data["_id"] = nId; - } - return await Http.put( - Url.addTask, - data, - ); - } - return await Http.post( - Url.addTask, - data, - ); - } - - static Future> delTask(String cron) async { - return await Http.delete( - Url.addTask, - [cron], - ); - } - - static Future> pinTask(String cron) async { - return await Http.put( - Url.pinTask, - [cron], - ); - } - - static Future> unpinTask(String cron) async { - return await Http.put( - Url.unpinTask, - [cron], - ); - } - - static Future> enableTask(String cron) async { - return await Http.put( - Url.enableTask, - [cron], - ); - } - - static Future> disableTask(String cron) async { - return await Http.put( - Url.disableTask, - [cron], - ); - } - - static Future>> files() async { - return await Http.get>( - Url.files, - null, - ); - } - - static Future> content(String name) async { - return await Http.get( - Url.configContent + name, - null, - ); - } - - static Future> saveFile(String name, String content) async { - return await Http.post( - Url.saveFile, - {"content": content, "name": name}, - ); - } - - static Future>> envs(String search) async { - return await Http.get>( - Url.envs, - {"searchValue": search}, - ); - } - - static Future> enableEnv(String id) async { - return await Http.put( - Url.enableEnvs, - [id], - ); - } - - static Future> disableEnv(String id) async { - return await Http.put( - Url.disableEnvs, - [id], - ); - } - - static Future> delEnv(String id) async { - return await Http.delete( - Url.delEnv, - [id], - ); - } - - static Future> addEnv( - String name, - String value, - String remarks, { - int? id, - String? nId, - }) async { - var data = { - "value": value, - "remarks": remarks, - "name": name, - }; - - if (id != null || nId != null) { - if (id != null) { - data["id"] = id; - } else if (nId != null) { - data["_id"] = nId; - } - return await Http.put( - Url.addEnv, - data, - ); - } - return await Http.post( - Url.addEnv, - [data], - ); - } - - static Future> moveEnv(String id, int fromIndex, int toIndex) async { - return await Http.put( - Url.envMove(id), - {"fromIndex": fromIndex, "toIndex": toIndex}, - ); - } - - static Future>> loginLog() async { - return await Http.get>( - Url.loginLog, - null, - ); - } - - static Future>> taskLog() async { - return await Http.get>(Url.taskLog, null, serializationName: Utils.isUpperVersion2_12_2() ? "data" : "dirs"); - } - - static Future> taskLogDetail(String name, String path) async { - if (Utils.isUpperVersion2_13_0()) { - return await Http.get( - Url.taskLogDetail + name + "?path=" + path, - null, - ); - } else { - return await Http.get( - Url.taskLogDetail + path + "/" + name, - null, - ); - } - } - - static Future>> scripts() async { - //2.12.2以及以上版本,脚本路径url做了修改 - return await Http.get>( - Utils.isUpperVersion2_13_0() ? Url.scripts2 : Url.scripts, - null, - ); - } - - static Future> updateScript(String name, String path, String content) async { - return await Http.put( - Url.scriptDetail, - { - "filename": name, - "path": path, - "content": content, - }, - ); - } - - static Future> delScript(String name, String path) async { - return await Http.delete( - Url.scriptDetail, - { - "filename": name, - "path": path, - }, - ); - } - - static Future> scriptDetail(String name, String? path) async { - return await Http.get( - Url.scriptDetail + name, - { - "path": path, - }, - ); - } - - static Future>> dependencies(String type) async { - return await Http.get>( - Url.dependencies, - { - "type": type.toString(), - }, - ); - } - - static Future> dependencyReinstall(String id) async { - return await Http.put( - Url.dependencies, - [id], - ); - } - - static Future> dependencyLog(String id) async { - return await Http.get( - Url.dependencies + "/" + id, - null, - ); - } - - static Future> addDependency(List> list) async { - return await Http.post( - Url.dependencies, - list, - ); - } - - static Future> addScript(String name, String path, String content) async { - return await Http.post( - Url.addScript, - { - "filename": name, - "path": path, - "content": content, - }, - ); - } - - static Future> delDependency(String id) async { - return await Http.delete( - Url.dependencies, - [id], - ); - } - - - // 获取订阅 - static Future>> getSubscription()async{ - return await Http.get>( - Url.subscriptions, - {} - ); - } - - // 新增订阅 - static Future> postSubscription(Subscription subscription)async{ - var data = subscription.toJson(); - data.remove("id"); - data.remove("status"); - data.remove("pid"); - data.remove("log_path"); - data.remove("is_disabled"); - data.remove("createdAt"); - data.remove("updatedAt"); - data.remove("pullType"); - data.remove("pullOption"); - return await Http.post( - Url.subscriptions, - data - ); - } - - // 修改订阅 - static Future> putSubscription(Subscription subscription)async{ - return await Http.put( - Url.subscriptions, - subscription.toJson() - ); - } - - // 删除订阅 参数未一个id数组 - static Future> deleteSubscription(List ids)async{ - return await Http.delete( - Url.subscriptions, - ids - ); - } - - // 删除订阅 参数未一个id数组 - static Future> disableSubscription(List ids)async{ - return await Http.put( - Url.disableSubscriptions, - ids - ); - } - - // 删除订阅 参数未一个id数组 - static Future> enableSubscription(List ids)async{ - return await Http.put( - Url.enableSubscriptions, - ids - ); - } - - // 开始执行订阅 - static Future> startSubscription( - List subscriptions) async { - return await Http.put( - Url.runSubscriptions, - subscriptions, - ); - } - - // 暂停订阅执行 - static Future> stopSubscription( - List subscriptions) async { - return await Http.put( - Url.stopSubscriptions, - subscriptions, - ); - } - - // 获取订阅的日志 - static Future> subTimeLog(int subId) async { - return await Http.get( - Url.subtimeLog(subId), - null, - ); - } -} diff --git a/lib/base/http/http.dart b/lib/base/http/http.dart deleted file mode 100644 index 915cd0a..0000000 --- a/lib/base/http/http.dart +++ /dev/null @@ -1,266 +0,0 @@ -import 'dart:convert'; -import 'dart:core'; - -import 'package:dio/dio.dart'; -import 'package:dio_log/dio_log.dart'; -import 'package:flutter/foundation.dart'; -import 'package:qinglong_app/base/http/token_interceptor.dart'; -import 'package:qinglong_app/base/http/url.dart'; -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -import '../../json.jc.dart'; -import '../../main.dart'; -import '../routes.dart'; - -class Http { - static Dio? _dio; - static bool pushedLoginPage = false; - - static void initDioConfig( - String host, - ) { - _dio = Dio( - BaseOptions( - baseUrl: host, - connectTimeout: 50000, - receiveTimeout: 50000, - sendTimeout: 50000, - contentType: "application/json", - ), - ); - _dio?.interceptors.add(DioLogInterceptor()); - _dio?.interceptors.add(TokenInterceptor()); - } - - static void _init() { - if (_dio == null) { - initDioConfig(getIt().host!); - } - } - - static void clear() { - _dio = null; - } - - static Future> get( - String uri, - Map? json, { - bool compute = true, - String serializationName = "data", - }) async { - try { - _init(); - var response = await _dio!.get(uri, queryParameters: json); - - return decodeResponse(response, serializationName, compute); - } on DioError catch (e) { - return exceptionHandler(e, uri); - } - } - - static Future> post( - String uri, - dynamic json, { - bool compute = true, - String serializationName = "data", - }) async { - try { - _init(); - var response = await _dio!.post(uri, data: json); - - return decodeResponse( - response, - serializationName, - compute, - ); - } on DioError catch (e) { - return exceptionHandler(e, uri); - } - } - - static Future> delete( - String uri, - dynamic json, { - bool compute = true, - String serializationName = "data", - }) async { - try { - _init(); - var response = await _dio!.delete(uri, data: json); - - return decodeResponse( - response, - serializationName, - compute, - ); - } on DioError catch (e) { - return exceptionHandler(e, uri); - } - } - - static Future> put( - String uri, - dynamic json, { - bool compute = true, - String serializationName = "data", - }) async { - try { - _init(); - var response = await _dio!.put(uri, data: json); - return decodeResponse( - response, - serializationName, - compute, - ); - } on DioError catch (e) { - return exceptionHandler(e, uri); - } - } - - static void exitLogin() { - if (!pushedLoginPage) { - "身份已过期,请重新登录".toast(); - pushedLoginPage = true; - navigatorState.currentState - ?.pushNamedAndRemoveUntil(Routes.routeLogin, (route) => false); - } - } - - static HttpResponse exceptionHandler(DioError e, String path) { - logger.e(e); - if (e.response?.statusCode == 401 && !Url.inWhiteList(path)) { - if (!getIt().useSecretLogined) { - exitLogin(); - } - return HttpResponse(success: false, message: "没有该模块的访问权限", code: 401); - } - - if (e.response != null && e.response!.data != null) { - return HttpResponse( - success: false, - message: e.response?.data["message"] ?? e.message, - code: e.response?.data["code"] ?? 0); - } else { - return HttpResponse( - success: false, - message: e.message, - code: e.response?.statusCode ?? 0); - } - } - - static HttpResponse decodeResponse( - Response response, - String serializationName, - bool compute, - ) { - int code = 0; - if (response.statusCode == 200) { - try { - if (response.data["code"] == 200) { - if (response.data[serializationName] != null) { - if (T == NullResponse) { - return HttpResponse( - success: true, - code: 200, - ); - } - - dynamic data = response.data[serializationName]; - T t; - if (T == String) { - if (data is String) { - t = data as T; - } else { - t = jsonEncode(data) as T; - } - return HttpResponse( - success: true, - code: 200, - bean: t, - ); - } else { - T bean; - if (compute) { - bean = DeserializeAction.invokeJson(DeserializeAction(data)); - } else { - bean = JsonConversion$Json.fromJson(data); - } - return HttpResponse( - success: true, - code: 200, - bean: bean, - ); - } - } else { - return HttpResponse( - success: true, - code: 200, - ); - } - } else { - return HttpResponse( - success: false, - code: response.data["code"], - message: response.data["message"], - ); - } - } catch (e) { - logger.e(e); - return HttpResponse( - success: false, - code: -1000, - message: "json解析失败", - ); - } - } else { - code = response.statusCode ?? 0; - return HttpResponse( - success: false, - code: code, - message: response.statusMessage, - ); - } - } -} - -class HttpResponse { - late bool success; - String? message; - late int code; - T? bean; - - HttpResponse( - {required this.success, this.message, required this.code, this.bean}); -} - -class DeserializeAction { - final dynamic json; - - DeserializeAction(this.json); - - T invoke() { - return JsonConversion$Json.fromJson(json); - } - - static dynamic invokeJson(DeserializeAction a) => a.invoke(); -} - -mixin BaseBean { - T fromJson(Map json); -} - -class CronBean with BaseBean { - @override - CronBean fromJson(Map json) { - return CronBean(); - } -} - -void decode() async { - compute(DeserializeAction.invokeJson, DeserializeAction({})); -} - -class NullResponse {} - -class NotLoginException implements Exception {} diff --git a/lib/base/http/token_interceptor.dart b/lib/base/http/token_interceptor.dart deleted file mode 100644 index 821e618..0000000 --- a/lib/base/http/token_interceptor.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:dio/dio.dart'; -import 'package:qinglong_app/base/http/url.dart'; -import 'package:qinglong_app/main.dart'; - -import '../userinfo_viewmodel.dart'; - -class TokenInterceptor extends Interceptor { - @override - void onRequest(RequestOptions options, RequestInterceptorHandler handler) { - options.headers["User-Agent"] = "qinglong_client"; - - options.headers["Content-Type"] = "application/json;charset=UTF-8"; - - if (!Url.inWhiteList(options.path)) { - options.queryParameters["t"] = - (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(); - } - - if (!Url.inLoginList(options.path)) { - if (getIt().token != null && - getIt().token!.isNotEmpty) { - options.headers["Authorization"] = - "Bearer " + getIt().token!; - } - } - return handler.next(options); - } -} diff --git a/lib/base/http/url.dart b/lib/base/http/url.dart deleted file mode 100644 index aabb9f4..0000000 --- a/lib/base/http/url.dart +++ /dev/null @@ -1,181 +0,0 @@ -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/main.dart'; - -class Url { - static get login => "/api/user/login"; - - static get system => "/api/system"; - - static get loginOld => "/api/login"; - - static get loginTwo => "/api/user/two-factor/login"; - static const loginByClientId = "/open/auth/token"; - static const user = "/api/user"; - - static const updatePassword = "/api/user"; - - static get tasks => getIt().useSecretLogined - ? "/open/crons" - : "/api/crons"; - - static get runTasks => getIt().useSecretLogined - ? "/open/crons/run" - : "/api/crons/run"; - - static get stopTasks => getIt().useSecretLogined - ? "/open/crons/stop" - : "/api/crons/stop"; - - static get taskDetail => getIt().useSecretLogined - ? "/open/crons/" - : "/api/crons/"; - - static get addTask => getIt().useSecretLogined - ? "/open/crons" - : "/api/crons"; - - static get pinTask => getIt().useSecretLogined - ? "/open/crons/pin" - : "/api/crons/pin"; - - static get unpinTask => getIt().useSecretLogined - ? "/open/crons/unpin" - : "/api/crons/unpin"; - - static get enableTask => getIt().useSecretLogined - ? "/open/crons/enable" - : "/api/crons/enable"; - - static get disableTask => getIt().useSecretLogined - ? "/open/crons/disable" - : "/api/crons/disable"; - - static get files => getIt().useSecretLogined - ? "/open/configs/files" - : "/api/configs/files"; - - static get configContent => getIt().useSecretLogined - ? "/open/configs/" - : "/api/configs/"; - - static get saveFile => getIt().useSecretLogined - ? "/open/configs/save" - : "/api/configs/save"; - - static get envs => - getIt().useSecretLogined ? "/open/envs" : "/api/envs"; - - static get addEnv => - getIt().useSecretLogined ? "/open/envs" : "/api/envs"; - - static get delEnv => - getIt().useSecretLogined ? "/open/envs" : "/api/envs"; - - static get disableEnvs => getIt().useSecretLogined - ? "/open/envs/disable" - : "/api/envs/disable"; - - static get enableEnvs => getIt().useSecretLogined - ? "/open/envs/enable" - : "/api/envs/enable"; - - static get loginLog => getIt().useSecretLogined - ? "/open/user/login-log" - : "/api/user/login-log"; - - static get taskLog => - getIt().useSecretLogined ? "/open/logs" : "/api/logs"; - - static get taskLogDetail => getIt().useSecretLogined - ? "/open/logs/" - : "/api/logs/"; - - static get scripts => getIt().useSecretLogined - ? "/open/scripts/files" - : "/api/scripts/files"; - - static get scripts2 => getIt().useSecretLogined - ? "/open/scripts" - : "/api/scripts"; - - static get scriptUpdate => getIt().useSecretLogined - ? "/open/scripts" - : "/api/scripts"; - - static get scriptDetail => getIt().useSecretLogined - ? "/open/scripts/" - : "/api/scripts/"; - - static get dependencies => getIt().useSecretLogined - ? "/open/dependencies" - : "/api/dependencies"; - - static get addScript => getIt().useSecretLogined - ? "/open/scripts" - : "/api/scripts"; - - static get dependencyReinstall => getIt().useSecretLogined - ? "/open/dependencies/reinstall" - : "/api/dependencies/reinstall"; - - static intimeLog(String cronId) { - return getIt().useSecretLogined - ? "/open/crons/$cronId/log" - : "/api/crons/$cronId/log"; - } - - static envMove(String envId) { - return getIt().useSecretLogined - ? "/open/envs/$envId/move" - : "/api/envs/$envId/move"; - } - - // 运行订阅 - static get runSubscriptions => getIt().useSecretLogined - ? "/open/subscriptions/run" - : "/api/subscriptions/run"; - - // 停止订阅 - static get stopSubscriptions => getIt().useSecretLogined - ? "/open/subscriptions/stop" - : "/api/subscriptions/stop"; - - // 启用订阅 - static get enableSubscriptions => getIt().useSecretLogined - ? "/open/subscriptions/enable" - : "/api/subscriptions/enable"; - - // 禁用订阅 - static get disableSubscriptions => getIt().useSecretLogined - ? "/open/subscriptions/disable" - : "/api/subscriptions/disable"; - - // GET 获取订阅 POST 提交订阅 PUT 修改订阅 DELETE 删除订阅 - static get subscriptions => getIt().useSecretLogined - ? "/open/subscriptions" - : "/api/subscriptions"; - - // 获取订阅日志 - static subtimeLog(int cronId) { - return getIt().useSecretLogined - ? "/open/subscriptions/$cronId/log" - : "/api/subscriptions/$cronId/log"; - } - - static bool inWhiteList(String path) { - if (path == login || - path == loginByClientId || - path == loginTwo || - path == loginOld) { - return true; - } - return false; - } - - static bool inLoginList(String path) { - if (path == login || path == loginByClientId || path == loginOld) { - return true; - } - return false; - } -} diff --git a/lib/base/ql_app_bar.dart b/lib/base/ql_app_bar.dart deleted file mode 100644 index 6ace816..0000000 --- a/lib/base/ql_app_bar.dart +++ /dev/null @@ -1,56 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; - -class QlAppBar extends StatelessWidget with PreferredSizeWidget { - final String title; - final List? actions; - final VoidCallback? backCall; - final bool canBack; - final Widget? backWidget; - - QlAppBar({ - Key? key, - required this.title, - this.actions, - this.backCall, - this.canBack = true, - this.backWidget, - }) : super(key: key); - - @override - Widget build(BuildContext context) { - Widget back = backWidget ?? - InkWell( - onTap: () { - if (backCall != null) { - backCall!(); - } else { - Navigator.of(context).pop(); - } - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - CupertinoIcons.left_chevron, - color: Colors.white, - ), - ), - ), - ); - - return AppBar( - elevation: 0, - leading: canBack ? back : null, - automaticallyImplyLeading: canBack, - title: Text(title), - centerTitle: true, - actions: [...?actions], - ); - } - - @override - Size get preferredSize => const Size.fromHeight(kToolbarHeight); -} diff --git a/lib/base/routes.dart b/lib/base/routes.dart deleted file mode 100644 index 7d4d91a..0000000 --- a/lib/base/routes.dart +++ /dev/null @@ -1,201 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:qinglong_app/module/change_account_page.dart'; -import 'package:qinglong_app/module/config/config_edit_page.dart'; -import 'package:qinglong_app/module/env/add_env_page.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/module/env/env_detail_page.dart'; -import 'package:qinglong_app/module/home/home_page.dart'; -import 'package:qinglong_app/module/login/login_page.dart'; -import 'package:qinglong_app/module/others/about_page.dart'; -import 'package:qinglong_app/module/others/backup/backup_page.dart'; -import 'package:qinglong_app/module/others/dependencies/add_dependency_page.dart'; -import 'package:qinglong_app/module/others/dependencies/dependency_page.dart'; -import 'package:qinglong_app/module/others/login_log/login_log_page.dart'; -import 'package:qinglong_app/module/others/scripts/script_detail_page.dart'; -import 'package:qinglong_app/module/others/scripts/script_edit_page.dart'; -import 'package:qinglong_app/module/others/scripts/script_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_add_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_bean.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_detail_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:qinglong_app/module/others/task_log/task_log_detail_page.dart'; -import 'package:qinglong_app/module/others/task_log/task_log_page.dart'; -import 'package:qinglong_app/module/others/theme_page.dart'; -import 'package:qinglong_app/module/others/update_password_page.dart'; -import 'package:qinglong_app/module/task/add_task_page.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/module/task/task_detail/task_detail_page.dart'; - -import '../module/others/scripts/script_add_page.dart'; - -class Routes { - static const String routeHomePage = "/home/homepage"; - static const String routeLogin = "/login"; - static const String routeAddTask = "/task/add"; - static const String routeTaskDetail = "/task/detail"; - static const String routeEnvDetail = "/env/detail"; - static const String routeAddDependency = "/task/dependency"; - static const String routeAddEnv = "/env/add"; - static const String routeConfigEdit = "/config/edit"; - static const String routeLoginLog = "/log/login"; - static const String routeTaskLog = "/log/task"; - static const String routeTaskLogDetail = "/log/taskDetail"; - static const String routeScript = "/script"; - static const String routeScriptDetail = "/script/detail"; - static const String routeScriptUpdate = "/script/update"; - static const String routeScriptAdd = "/script/add"; - static const String routeDependency = "/Dependency"; - static const String routeUpdatePassword = "/updatePassword"; - static const String routeAbout = "/about"; - static const String routeTheme = "/theme"; - static const String routeChangeAccount = "/changeAccount"; - static const String routerAddScript = "/script/add"; - static const String routerSubscription = "/subscription"; - static const String routerSubscriptionDetail = "/subscription/detail"; - static const String routerSubscriptionAdd = "/subscription/add"; - - static const String routerBackup = "/backup"; - - static Route? generateRoute(RouteSettings settings) { - switch (settings.name) { - case routeHomePage: - return MaterialPageRoute(builder: (context) => const HomePage()); - case routeLogin: - if (settings.arguments != null) { - return MaterialPageRoute( - builder: (context) => const LoginPage( - doNotLoadLocalData: true, - )); - } else { - return MaterialPageRoute(builder: (context) => const LoginPage()); - } - case routeChangeAccount: - return MaterialPageRoute( - builder: (context) => const ChangeAccountPage(), - ); - case routeAddTask: - if (settings.arguments != null) { - return MaterialPageRoute( - builder: (context) => AddTaskPage( - taskBean: settings.arguments as TaskBean, - )); - } else { - return MaterialPageRoute(builder: (context) => const AddTaskPage()); - } - case routeAddDependency: - return MaterialPageRoute(builder: (context) => const AddDependencyPage()); - case routeAddEnv: - if (settings.arguments != null) { - return MaterialPageRoute( - builder: (context) => AddEnvPage( - envBean: settings.arguments as EnvBean, - )); - } else { - return MaterialPageRoute(builder: (context) => const AddEnvPage()); - } - case routeConfigEdit: - return MaterialPageRoute( - builder: (context) => ConfigEditPage( - (settings.arguments as Map)["title"], - (settings.arguments as Map)["content"], - ), - ); - case routeLoginLog: - return MaterialPageRoute( - builder: (context) => const LoginLogPage(), - ); - case routeTaskLog: - return MaterialPageRoute( - builder: (context) => const TaskLogPage(), - ); - case routeScript: - return MaterialPageRoute( - builder: (context) => const ScriptPage(), - ); - case routeDependency: - return MaterialPageRoute( - builder: (context) => const DependencyPage(), - ); - case routeTaskLogDetail: - return MaterialPageRoute( - builder: (context) => TaskLogDetailPage( - title: (settings.arguments as Map)['title'], - path: (settings.arguments as Map)['path'], - ), - ); - case routeScriptDetail: - return MaterialPageRoute( - builder: (context) => ScriptDetailPage( - title: (settings.arguments as Map)["title"], - path: (settings.arguments as Map)["path"], - ), - ); - case routeTaskDetail: - return MaterialPageRoute( - builder: (context) => TaskDetailPage( - settings.arguments as TaskBean, - ), - ); - case routeEnvDetail: - return MaterialPageRoute( - builder: (context) => EnvDetailPage( - settings.arguments as EnvBean, - ), - ); - case routeUpdatePassword: - return MaterialPageRoute( - builder: (context) => const UpdatePasswordPage(), - ); - case routeAbout: - return MaterialPageRoute( - builder: (context) => const AboutPage(), - ); - case routeTheme: - return MaterialPageRoute( - builder: (context) => const ThemePage(), - ); - case routeScriptUpdate: - return MaterialPageRoute( - builder: (context) => ScriptEditPage( - (settings.arguments as Map)["title"], - (settings.arguments as Map)["path"], - (settings.arguments as Map)["content"], - ), - ); - case routeScriptAdd: - return MaterialPageRoute( - builder: (context) => ScriptAddPage( - (settings.arguments as Map)["title"], - (settings.arguments as Map)["path"], - ), - ); - case routerSubscription: - //部分低端手机用Cupertino滑动时掉帧,左侧会出现白色空白 - return MaterialPageRoute( - builder: (context) => const SubscriptionPage(), - ); - case routerSubscriptionDetail: - return MaterialPageRoute( - builder: (context) => SubscriptionDetailPage( - settings.arguments as Subscription, - ), - ); - case routerSubscriptionAdd: - if (settings.arguments != null) { - return MaterialPageRoute( - builder: (context) => SubscriptionAddPage( - settings.arguments as Subscription, - )); - } else { - return MaterialPageRoute(builder: (context) => const SubscriptionAddPage(null)); - } - case routerBackup: - return MaterialPageRoute( - builder: (context) => const BackUpPage(), - ); - } - - return null; - } -} diff --git a/lib/base/sp_const.dart b/lib/base/sp_const.dart deleted file mode 100644 index a34e305..0000000 --- a/lib/base/sp_const.dart +++ /dev/null @@ -1,9 +0,0 @@ -String spUserInfo = "userinfo"; -String spHost = "host"; -String spUserName = "username"; -String spPassWord = "password"; -String spTheme = "dart_mode"; -String spSecretLogined = "secret_logined"; -String spCustomColor = "customColor"; -String spLoginHistory = "loginHistory"; -String spShowLine = "spShowLine"; diff --git a/lib/base/theme.dart b/lib/base/theme.dart deleted file mode 100644 index 19764a9..0000000 --- a/lib/base/theme.dart +++ /dev/null @@ -1,327 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/sp_const.dart'; -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/main.dart'; -import 'package:qinglong_app/utils/codeeditor_theme.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -var themeProvider = ChangeNotifierProvider((ref) => ThemeViewModel()); - -Color commonColor = const Color(0xFF299343); -Color _primaryColor = commonColor; - -class ThemeViewModel extends ChangeNotifier { - late ThemeData currentTheme; - - bool _isInDarkMode = false; - Color primaryColor = commonColor; - - ThemeColors themeColor = LightThemeColors(); - - ThemeViewModel() { - _primaryColor = Color(getIt().primaryColor); - primaryColor = Color(getIt().primaryColor); - var brightness = SchedulerBinding.instance.window.platformBrightness; - _isInDarkMode = brightness == Brightness.dark; - changeThemeReal(_isInDarkMode, false); - } - - bool isInDartMode() { - return SpUtil.getBool(spTheme, defValue: false); - } - - void changeThemeReal(bool dark, [bool notify = true]) { - _isInDarkMode = dark; - SpUtil.putBool(spTheme, dark); - if (!dark) { - currentTheme = getLightTheme(); - themeColor = LightThemeColors(); - } else { - currentTheme = getDartTheme(); - themeColor = DartThemeColors(); - } - if (notify) { - notifyListeners(); - } - } - - get darkMode => _isInDarkMode; - - void changePrimaryColor(Color color) { - _primaryColor = color; - primaryColor = color; - getIt().updateCustomColor(color.value); - changeThemeReal(SpUtil.getBool(spTheme, defValue: false), true); - } - - void changeTheme() { - changeThemeReal(!SpUtil.getBool(spTheme, defValue: false), true); - } - - ThemeData getLightTheme() { - return ThemeData.light().copyWith( - brightness: Brightness.light, - primaryColor: _primaryColor, - colorScheme: ColorScheme.light( - secondary: _primaryColor, - primary: _primaryColor, - ), - scaffoldBackgroundColor: const Color(0xffffffff), - inputDecorationTheme: InputDecorationTheme( - labelStyle: TextStyle( - color: _primaryColor, - fontSize: 14, - ), - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: _primaryColor, - ), - ), - border: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color(0xff999999), - ), - ), - enabledBorder: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color(0xff999999), - ), - ), - ), - appBarTheme: AppBarTheme( - backgroundColor: _primaryColor, - titleTextStyle: const TextStyle( - color: Colors.white, - fontSize: 18, - ), - ), - bottomNavigationBarTheme: BottomNavigationBarThemeData( - selectedItemColor: _primaryColor, - ), - buttonTheme: ButtonThemeData( - buttonColor: _primaryColor, - ), - progressIndicatorTheme: ProgressIndicatorThemeData( - color: _primaryColor, - ), - tabBarTheme: TabBarTheme( - labelStyle: const TextStyle( - fontSize: 14, - ), - unselectedLabelStyle: const TextStyle( - fontSize: 14, - ), - labelColor: _primaryColor, - unselectedLabelColor: const Color(0xff999999), - indicator: UnderlineTabIndicator( - borderSide: BorderSide(color: _primaryColor), - ), - ), - toggleableActiveColor: _primaryColor, - checkboxTheme: CheckboxThemeData( - checkColor: MaterialStateProperty.resolveWith( - (Set states) { - if (states.contains(MaterialState.disabled)) { - return Colors.transparent; - } - if (states.contains(MaterialState.selected)) { - return Colors.white; - } - return Colors.black; - }, - ), - ), - cupertinoOverrideTheme: NoDefaultCupertinoThemeData( - brightness: Brightness.light, - primaryColor: _primaryColor, - scaffoldBackgroundColor: const Color(0xfff5f5f5), - ), - ); - } - - ThemeData getDartTheme() { - return ThemeData.dark().copyWith( - brightness: Brightness.dark, - primaryColor: const Color(0xffffffff), - scaffoldBackgroundColor: Colors.black, - appBarTheme: const AppBarTheme( - backgroundColor: Colors.black, - titleTextStyle: TextStyle( - color: Colors.white, - fontSize: 18, - ), - ), - inputDecorationTheme: InputDecorationTheme( - labelStyle: TextStyle( - color: _primaryColor, - fontSize: 14, - ), - focusedBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: _primaryColor, - ), - ), - border: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color(0xff999999), - ), - ), - enabledBorder: const UnderlineInputBorder( - borderSide: BorderSide( - color: Color(0xff999999), - ), - ), - ), - tabBarTheme: const TabBarTheme( - labelStyle: TextStyle( - fontSize: 14, - ), - unselectedLabelStyle: TextStyle( - fontSize: 14, - ), - labelColor: Color(0xffffffff), - unselectedLabelColor: Color(0xff999999), - ), - colorScheme: ColorScheme.light( - secondary: _primaryColor, - primary: _primaryColor, - ), - toggleableActiveColor: _primaryColor, - checkboxTheme: CheckboxThemeData( - checkColor: MaterialStateProperty.resolveWith( - (Set states) { - if (states.contains(MaterialState.disabled)) { - return Colors.transparent; - } - if (states.contains(MaterialState.selected)) { - return Colors.white; - } - return Colors.white; - }, - ), - ), - cupertinoOverrideTheme: const NoDefaultCupertinoThemeData( - brightness: Brightness.dark, - primaryColor: Color(0xffffffff), - scaffoldBackgroundColor: Colors.black, - ), - ); - } -} - -abstract class ThemeColors { - Color settingBgColor(); - - Color settingBordorColor(); - - Color titleColor(); - - Color descColor(); - - Color tabBarColor(); - - Color blackAndWhite(); - - Color pinColor(); - - Color buttonBgColor(); - - Map codeEditorTheme(); -} - -class LightThemeColors extends ThemeColors { - @override - Color titleColor() { - return const Color(0xff333333); - } - - @override - Color pinColor() { - return const Color(0xffF7F7F7); - } - - @override - Color blackAndWhite() { - return Colors.white; - } - - @override - Map codeEditorTheme() { - return qinglongLightTheme; - } - - @override - Color descColor() { - return const Color(0xff999999); - } - - @override - Color settingBgColor() { - return Colors.white; - } - - @override - Color buttonBgColor() { - return _primaryColor; - } - - @override - Color settingBordorColor() { - return Colors.white; - } - - @override - Color tabBarColor() { - return const Color(0xffF7F7F7); - } -} - -class DartThemeColors extends ThemeColors { - @override - Color titleColor() { - return Colors.white; - } - - @override - Color pinColor() { - return Colors.black12; - } - - @override - Map codeEditorTheme() { - return qinglongDarkTheme; - } - - @override - Color blackAndWhite() { - return Colors.black; - } - - @override - Color descColor() { - return const Color(0xff999999); - } - - @override - Color settingBgColor() { - return Colors.black; - } - - @override - Color buttonBgColor() { - return const Color(0xff333333); - } - - @override - Color settingBordorColor() { - return Color(0xff333333); - } - - @override - Color tabBarColor() { - return Colors.black; - } -} diff --git a/lib/base/ui/abs_underline_tabindicator.dart b/lib/base/ui/abs_underline_tabindicator.dart deleted file mode 100644 index 7b258b0..0000000 --- a/lib/base/ui/abs_underline_tabindicator.dart +++ /dev/null @@ -1,76 +0,0 @@ -import 'package:flutter/material.dart'; - -///tabbar样式下方横条固定宽度 -class AbsUnderlineTabIndicator extends Decoration { - const AbsUnderlineTabIndicator({ - this.wantWidth, - this.borderSide = const BorderSide(width: 2.0, color: Colors.white), - this.insets = EdgeInsets.zero, - }) : assert(borderSide != null), - assert(insets != null); - - final BorderSide? borderSide; - final double? wantWidth; - - final EdgeInsetsGeometry? insets; - - @override - Decoration? lerpFrom(Decoration? a, double t) { - if (a is UnderlineTabIndicator) { - return UnderlineTabIndicator( - borderSide: BorderSide.lerp(a.borderSide, borderSide!, t), - insets: EdgeInsetsGeometry.lerp(a.insets, insets, t)!, - ); - } - return super.lerpFrom(a, t); - } - - @override - Decoration? lerpTo(Decoration? b, double t) { - if (b is UnderlineTabIndicator) { - return UnderlineTabIndicator( - borderSide: BorderSide.lerp(borderSide!, b.borderSide, t), - insets: EdgeInsetsGeometry.lerp(insets, b.insets, t)!, - ); - } - return super.lerpTo(b, t); - } - - @override - _UnderlinePainter createBoxPainter([VoidCallback? onChanged]) { - return _UnderlinePainter(this, onChanged); - } -} - -class _UnderlinePainter extends BoxPainter { - _UnderlinePainter(this.decoration, VoidCallback? onChanged) - : super(onChanged); - - final AbsUnderlineTabIndicator decoration; - - BorderSide? get borderSide => decoration.borderSide; - - EdgeInsetsGeometry? get insets => decoration.insets; - - Rect _indicatorRectFor(Rect rect, TextDirection textDirection) { - final Rect indicator = insets!.resolve(textDirection).deflateRect(rect); - //取中间坐标 - double cw = (indicator.left + indicator.right) / 2; - return Rect.fromLTWH( - cw - decoration.wantWidth! / 2, - indicator.bottom - borderSide!.width, - decoration.wantWidth!, - borderSide!.width); - } - - @override - void paint(Canvas canvas, Offset offset, ImageConfiguration configuration) { - assert(configuration.size != null); - final Rect rect = offset & configuration.size!; - final TextDirection textDirection = configuration.textDirection!; - final Rect indicator = - _indicatorRectFor(rect, textDirection).deflate(borderSide!.width / 2.0); - final Paint paint = borderSide!.toPaint()..strokeCap = StrokeCap.round; - canvas.drawLine(indicator.bottomLeft, indicator.bottomRight, paint); - } -} diff --git a/lib/base/ui/empty_widget.dart b/lib/base/ui/empty_widget.dart deleted file mode 100644 index daf9125..0000000 --- a/lib/base/ui/empty_widget.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/theme.dart'; - -class EmptyWidget extends ConsumerWidget { - const EmptyWidget({Key? key}) : super(key: key); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - "暂无数据", - style: TextStyle( - fontSize: 14, - color: ref.watch(themeProvider).themeColor.descColor(), - ), - ), - ], - ), - ); - } -} diff --git a/lib/base/ui/lazy_load_state.dart b/lib/base/ui/lazy_load_state.dart deleted file mode 100644 index c6ed33f..0000000 --- a/lib/base/ui/lazy_load_state.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/material.dart'; - -/// @author NewTab - -mixin LazyLoadState on State { - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - var route = ModalRoute.of(context); - void handler(status) { - if (status == AnimationStatus.completed) { - route?.animation?.removeStatusListener(handler); - onLazyLoad(); - } - } - - if (route == null || - route.animation == null || - route.animation!.status == AnimationStatus.completed) { - onLazyLoad(); - } else { - route.animation!.addStatusListener(handler); - } - }); - } - - void onLazyLoad(); -} diff --git a/lib/base/ui/menu.dart b/lib/base/ui/menu.dart deleted file mode 100644 index 4c03878..0000000 --- a/lib/base/ui/menu.dart +++ /dev/null @@ -1,149 +0,0 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/widgets.dart'; - -/// A button in a _ContextMenuSheet. -/// -/// A typical use case is to pass a [Text] as the [child] here, but be sure to -/// use [TextOverflow.ellipsis] for the [Text.overflow] field if the text may be -/// long, as without it the text will wrap to the next line. -class QLCupertinoContextMenuAction extends StatefulWidget { - /// Construct a CupertinoContextMenuAction. - const QLCupertinoContextMenuAction({ - Key? key, - required this.child, - this.isDefaultAction = false, - this.isDestructiveAction = false, - this.onPressed, - this.trailingIcon, - }) : assert(child != null), - assert(isDefaultAction != null), - assert(isDestructiveAction != null), - super(key: key); - - /// The widget that will be placed inside the action. - final Widget child; - - /// Indicates whether this action should receive the style of an emphasized, - /// default action. - final bool isDefaultAction; - - /// Indicates whether this action should receive the style of a destructive - /// action. - final bool isDestructiveAction; - - /// Called when the action is pressed. - final VoidCallback? onPressed; - - /// An optional icon to display to the right of the child. - /// - /// Will be colored in the same way as the [TextStyle] used for [child] (for - /// example, if using [isDestructiveAction]). - final IconData? trailingIcon; - - @override - State createState() => - _QLCupertinoContextMenuActionState(); -} - -class _QLCupertinoContextMenuActionState - extends State { - static const Color _kBackgroundColor = Color(0xFFEEEEEE); - static const Color _kBackgroundColorPressed = Color(0xFFDDDDDD); - static const double _kButtonHeight = 30.0; - static const TextStyle _kActionSheetActionStyle = TextStyle( - fontFamily: '.SF UI Text', - inherit: false, - fontSize: 14.0, - fontWeight: FontWeight.w400, - color: CupertinoColors.black, - textBaseline: TextBaseline.alphabetic, - ); - - final GlobalKey _globalKey = GlobalKey(); - bool _isPressed = false; - - void onTapDown(TapDownDetails details) { - setState(() { - _isPressed = true; - }); - } - - void onTapUp(TapUpDetails details) { - setState(() { - _isPressed = false; - }); - } - - void onTapCancel() { - setState(() { - _isPressed = false; - }); - } - - TextStyle get _textStyle { - if (widget.isDefaultAction) { - return _kActionSheetActionStyle.copyWith( - fontWeight: FontWeight.w600, - ); - } - if (widget.isDestructiveAction) { - return _kActionSheetActionStyle.copyWith( - color: CupertinoColors.destructiveRed, - ); - } - return _kActionSheetActionStyle; - } - - @override - Widget build(BuildContext context) { - return GestureDetector( - key: _globalKey, - onTapDown: onTapDown, - onTapUp: onTapUp, - onTapCancel: onTapCancel, - onTap: widget.onPressed, - behavior: HitTestBehavior.opaque, - child: ConstrainedBox( - constraints: const BoxConstraints( - minHeight: _kButtonHeight, - ), - child: Semantics( - button: true, - child: Container( - decoration: BoxDecoration( - color: _isPressed ? _kBackgroundColorPressed : _kBackgroundColor, - border: const Border( - bottom: BorderSide(color: _kBackgroundColorPressed), - ), - ), - padding: const EdgeInsets.symmetric( - vertical: 10.0, - horizontal: 10.0, - ), - child: DefaultTextStyle( - style: _textStyle, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Flexible( - child: widget.child, - ), - if (widget.trailingIcon != null) - Icon( - widget.trailingIcon, - color: _textStyle.color, - size: 14, - ), - ], - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/base/ui/ql_context_menu.dart b/lib/base/ui/ql_context_menu.dart deleted file mode 100644 index a759ae9..0000000 --- a/lib/base/ui/ql_context_menu.dart +++ /dev/null @@ -1,1276 +0,0 @@ -/// @author NewTab -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:math' as math; -import 'dart:ui' as ui; -import 'package:flutter/gestures.dart' - show kMinFlingVelocity, kLongPressTimeout; -import 'package:flutter/scheduler.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; - -import '../routes.dart'; - -// The scale of the child at the time that the CupertinoContextMenu opens. -// This value was eyeballed from a physical device running iOS 13.1.2. -const double _kOpenScale = 1.1; - -typedef _DismissCallback = void Function( - BuildContext context, - double scale, - double opacity, -); - -/// A function that produces the preview when the CupertinoContextMenu is open. -/// -/// Called every time the animation value changes. -typedef ContextMenuPreviewBuilder = Widget Function( - BuildContext context, - Animation animation, - Widget child, -); - -// A function that proxies to ContextMenuPreviewBuilder without the child. -typedef _ContextMenuPreviewBuilderChildless = Widget Function( - BuildContext context, - Animation animation, -); - -// Given a GlobalKey, return the Rect of the corresponding RenderBox's -// paintBounds in global coordinates. -Rect _getRect(GlobalKey globalKey) { - assert(globalKey.currentContext != null); - final RenderBox renderBoxContainer = - globalKey.currentContext!.findRenderObject()! as RenderBox; - final Offset containerOffset = renderBoxContainer.localToGlobal( - renderBoxContainer.paintBounds.topLeft, - ); - return containerOffset & renderBoxContainer.paintBounds.size; -} - -// The context menu arranges itself slightly differently based on the location -// on the screen of [CupertinoContextMenu.child] before the -// [CupertinoContextMenu] opens. -enum _ContextMenuLocation { - center, - left, - right, -} - -/// A full-screen modal route that opens when the [child] is long-pressed. -/// -/// When open, the [QlCupertinoContextMenu] shows the child, or the widget returned -/// by [previewBuilder] if given, in a large full-screen [Overlay] with a list -/// of buttons specified by [actions]. The child/preview is placed in an -/// [Expanded] widget so that it will grow to fill the Overlay if its size is -/// unconstrained. -/// -/// When closed, the CupertinoContextMenu simply displays the child as if the -/// CupertinoContextMenu were not there. Sizing and positioning is unaffected. -/// The menu can be closed like other [PopupRoute]s, such as by tapping the -/// background or by calling `Navigator.pop(context)`. Unlike PopupRoute, it can -/// also be closed by swiping downwards. -/// -/// The [previewBuilder] parameter is most commonly used to display a slight -/// variation of [child]. See [previewBuilder] for an example of rounding the -/// child's corners and allowing its aspect ratio to expand, similar to the -/// Photos app on iOS. -/// -/// {@tool dartpad} -/// This sample shows a very simple CupertinoContextMenu for an empty red -/// 100x100 Container. Simply long press on it to open. -/// -/// ** See code in examples/api/lib/cupertino/context_menu/cupertino_context_menu.0.dart ** -/// {@end-tool} -/// -/// See also: -/// -/// * [Apple's HIG for Context Menus](https://developer.apple.com/design/human-interface-guidelines/ios/controls/context-menus/) -class QlCupertinoContextMenu extends StatefulWidget { - /// Create a context menu. - /// - /// [actions] is required and cannot be null or empty. - /// - /// [child] is required and cannot be null. - QlCupertinoContextMenu({ - Key? key, - required this.actions, - required this.child, - required this.bean, - this.previewBuilder, - }) : assert(actions != null && actions.isNotEmpty), - assert(child != null), - super(key: key); - - final T bean; - - /// The widget that can be "opened" with the [QlCupertinoContextMenu]. - /// - /// When the [QlCupertinoContextMenu] is long-pressed, the menu will open and - /// this widget (or the widget returned by [previewBuilder], if provided) will - /// be moved to the new route and placed inside of an [Expanded] widget. This - /// allows the child to resize to fit in its place in the new route, if it - /// doesn't size itself. - /// - /// When the [QlCupertinoContextMenu] is "closed", this widget acts like a - /// [Container], i.e. it does not constrain its child's size or affect its - /// position. - /// - /// This parameter cannot be null. - final Widget child; - - /// The actions that are shown in the menu. - /// - /// These actions are typically [CupertinoContextMenuAction]s. - /// - /// This parameter cannot be null or empty. - final List actions; - - /// A function that returns an alternative widget to show when the - /// [QlCupertinoContextMenu] is open. - /// - /// If not specified, [child] will be shown. - /// - /// The preview is often used to show a slight variation of the [child]. For - /// example, the child could be given rounded corners in the preview but have - /// sharp corners when in the page. - /// - /// In addition to the current [BuildContext], the function is also called - /// with an [Animation] and the [child]. The animation goes from 0 to 1 when - /// the CupertinoContextMenu opens, and from 1 to 0 when it closes, and it can - /// be used to animate the preview in sync with this opening and closing. The - /// child parameter provides access to the child displayed when the - /// CupertinoContextMenu is closed. - /// - /// {@tool snippet} - /// - /// Below is an example of using `previewBuilder` to show an image tile that's - /// similar to each tile in the iOS iPhoto app's context menu. Several of - /// these could be used in a GridView for a similar effect. - /// - /// When opened, the child animates to show its full aspect ratio and has - /// rounded corners. The larger size of the open CupertinoContextMenu allows - /// the FittedBox to fit the entire image, even when it has a very tall or - /// wide aspect ratio compared to the square of a GridView, so this animates - /// into view as the CupertinoContextMenu is opened. The preview is swapped in - /// right when the open animation begins, which includes the rounded corners. - /// - /// ```dart - /// CupertinoContextMenu( - /// child: FittedBox( - /// fit: BoxFit.cover, - /// child: Image.asset('assets/photo.jpg'), - /// ), - /// // The FittedBox in the preview here allows the image to animate its - /// // aspect ratio when the CupertinoContextMenu is animating its preview - /// // widget open and closed. - /// previewBuilder: (BuildContext context, Animation animation, Widget child) { - /// return FittedBox( - /// fit: BoxFit.cover, - /// // This ClipRRect rounds the corners of the image when the - /// // CupertinoContextMenu is open, even though it's not rounded when - /// // it's closed. It uses the given animation to animate the corners - /// // in sync with the opening animation. - /// child: ClipRRect( - /// borderRadius: BorderRadius.circular(64.0 * animation.value), - /// child: Image.asset('assets/photo.jpg'), - /// ), - /// ); - /// }, - /// actions: [ - /// CupertinoContextMenuAction( - /// child: const Text('Action one'), - /// onPressed: () {}, - /// ), - /// ], - /// ) - /// ``` - /// - /// {@end-tool} - final ContextMenuPreviewBuilder? previewBuilder; - - @override - State createState() => _QlCupertinoContextMenuState(); -} - -class _QlCupertinoContextMenuState extends State - with TickerProviderStateMixin { - final GlobalKey _childGlobalKey = GlobalKey(); - bool _childHidden = false; - - // Animates the child while it's opening. - late AnimationController _openController; - Rect? _decoyChildEndRect; - OverlayEntry? _lastOverlayEntry; - _ContextMenuRoute? _route; - - @override - void initState() { - super.initState(); - _openController = AnimationController( - duration: kLongPressTimeout, - vsync: this, - ); - _openController.addStatusListener(_onDecoyAnimationStatusChange); - } - - // Determine the _ContextMenuLocation based on the location of the original - // child in the screen. - // - // The location of the original child is used to determine how to horizontally - // align the content of the open CupertinoContextMenu. For example, if the - // child is near the center of the screen, it will also appear in the center - // of the screen when the menu is open, and the actions will be centered below - // it. - _ContextMenuLocation get _contextMenuLocation { - final Rect childRect = _getRect(_childGlobalKey); - final double screenWidth = MediaQuery.of(context).size.width; - - final double center = screenWidth / 2; - final bool centerDividesChild = - childRect.left < center && childRect.right > center; - final double distanceFromCenter = (center - childRect.center.dx).abs(); - if (centerDividesChild && distanceFromCenter <= childRect.width / 4) { - return _ContextMenuLocation.center; - } - - if (childRect.center.dx > center) { - return _ContextMenuLocation.right; - } - - return _ContextMenuLocation.left; - } - - // Push the new route and open the CupertinoContextMenu overlay. - void _openContextMenu() { - setState(() { - _childHidden = true; - }); - - _route = _ContextMenuRoute( - actions: widget.actions, - barrierLabel: 'Dismiss', - filter: ui.ImageFilter.blur( - sigmaX: 5.0, - sigmaY: 5.0, - ), - contextMenuLocation: _contextMenuLocation, - previousChildRect: _decoyChildEndRect!, - builder: (BuildContext context, Animation animation) { - if (widget.previewBuilder == null) { - return widget.child; - } - return widget.previewBuilder!(context, animation, widget.child); - }, - ); - Navigator.of(context, rootNavigator: true).push(_route!); - _route!.animation!.addStatusListener(_routeAnimationStatusListener); - } - - void _onDecoyAnimationStatusChange(AnimationStatus animationStatus) { - switch (animationStatus) { - case AnimationStatus.dismissed: - if (_route == null) { - setState(() { - _childHidden = false; - }); - } - _lastOverlayEntry?.remove(); - _lastOverlayEntry = null; - break; - - case AnimationStatus.completed: - setState(() { - _childHidden = true; - }); - _openContextMenu(); - // Keep the decoy on the screen for one extra frame. We have to do this - // because _ContextMenuRoute renders its first frame offscreen. - // Otherwise there would be a visible flash when nothing is rendered for - // one frame. - SchedulerBinding.instance!.addPostFrameCallback((Duration _) { - _lastOverlayEntry?.remove(); - _lastOverlayEntry = null; - _openController.reset(); - }); - break; - - case AnimationStatus.forward: - case AnimationStatus.reverse: - return; - } - } - - // Watch for when _ContextMenuRoute is closed and return to the state where - // the CupertinoContextMenu just behaves as a Container. - void _routeAnimationStatusListener(AnimationStatus status) { - if (status != AnimationStatus.dismissed) { - return; - } - setState(() { - _childHidden = false; - }); - _route!.animation!.removeStatusListener(_routeAnimationStatusListener); - _route = null; - } - - void _onTap() { - if (_openController.isAnimating && _openController.value < 0.5) { - _openController.reverse(); - } else { - if (_openController.isDismissed) { - if (widget.bean is TaskBean){ - Navigator.of(context) - .pushNamed(Routes.routeTaskDetail, arguments: widget.bean); - }else{ - Navigator.of(context) - .pushNamed(Routes.routerSubscriptionDetail, arguments: widget.bean); - } - - } - } - } - - void _onTapCancel() { - if (_openController.isAnimating && _openController.value < 0.5) { - _openController.reverse(); - } - } - - void _onTapUp(TapUpDetails details) { - if (_openController.isAnimating && _openController.value < 0.5) { - _openController.reverse(); - } - } - - void _onTapDown(TapDownDetails details) { - setState(() { - _childHidden = true; - }); - - final Rect childRect = _getRect(_childGlobalKey); - _decoyChildEndRect = Rect.fromCenter( - center: childRect.center, - width: childRect.width * _kOpenScale, - height: childRect.height * _kOpenScale, - ); - - // Create a decoy child in an overlay directly on top of the original child. - // TODO(justinmc): There is a known inconsistency with native here, due to - // doing the bounce animation using a decoy in the top level Overlay. The - // decoy will pop on top of the AppBar if the child is partially behind it, - // such as a top item in a partially scrolled view. However, if we don't use - // an overlay, then the decoy will appear behind its neighboring widget when - // it expands. This may be solvable by adding a widget to Scaffold that's - // underneath the AppBar. - _lastOverlayEntry = OverlayEntry( - builder: (BuildContext context) { - return _DecoyChild( - beginRect: childRect, - controller: _openController, - endRect: _decoyChildEndRect, - child: widget.child, - ); - }, - ); - Overlay.of(context, rootOverlay: true)!.insert(_lastOverlayEntry!); - _openController.forward(); - } - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTapCancel: _onTapCancel, - onTapDown: _onTapDown, - onTapUp: _onTapUp, - onTap: _onTap, - child: TickerMode( - enabled: !_childHidden, - child: Opacity( - key: _childGlobalKey, - opacity: _childHidden ? 0.0 : 1.0, - child: widget.child, - ), - ), - ); - } - - @override - void dispose() { - _openController.dispose(); - super.dispose(); - } -} - -// A floating copy of the CupertinoContextMenu's child. -// -// When the child is pressed, but before the CupertinoContextMenu opens, it does -// a "bounce" animation where it shrinks and then grows. This is implemented -// by hiding the original child and placing _DecoyChild on top of it in an -// Overlay. The use of an Overlay allows the _DecoyChild to appear on top of -// siblings of the original child. -class _DecoyChild extends StatefulWidget { - const _DecoyChild({ - Key? key, - this.beginRect, - required this.controller, - this.endRect, - this.child, - }) : super(key: key); - - final Rect? beginRect; - final AnimationController controller; - final Rect? endRect; - final Widget? child; - - @override - _DecoyChildState createState() => _DecoyChildState(); -} - -class _DecoyChildState extends State<_DecoyChild> - with TickerProviderStateMixin { - // TODO(justinmc): Dark mode support. - // See https://github.com/flutter/flutter/issues/43211. - static const Color _lightModeMaskColor = Color(0xFF888888); - static const Color _masklessColor = Color(0xFFFFFFFF); - - final GlobalKey _childGlobalKey = GlobalKey(); - late Animation _mask; - late Animation _rect; - - @override - void initState() { - super.initState(); - // Change the color of the child during the initial part of the decoy bounce - // animation. The interval was eyeballed from a physical iOS 13.1.2 device. - _mask = _OnOffAnimation( - controller: widget.controller, - onValue: _lightModeMaskColor, - offValue: _masklessColor, - intervalOn: 0.0, - intervalOff: 0.5, - ); - - final Rect midRect = widget.beginRect!.deflate( - widget.beginRect!.width * (_kOpenScale - 1.0) / 2, - ); - _rect = TweenSequence(>[ - TweenSequenceItem( - tween: RectTween( - begin: widget.beginRect, - end: midRect, - ).chain(CurveTween(curve: Curves.easeInOutCubic)), - weight: 1.0, - ), - TweenSequenceItem( - tween: RectTween( - begin: midRect, - end: widget.endRect, - ).chain(CurveTween(curve: Curves.easeOutCubic)), - weight: 1.0, - ), - ]).animate(widget.controller); - _rect.addListener(_rectListener); - } - - // Listen to the _rect animation and vibrate when it reaches the halfway point - // and switches from animating down to up. - void _rectListener() { - if (widget.controller.value < 0.5) { - return; - } - HapticFeedback.selectionClick(); - _rect.removeListener(_rectListener); - } - - @override - void dispose() { - _rect.removeListener(_rectListener); - super.dispose(); - } - - Widget _buildAnimation(BuildContext context, Widget? child) { - final Color color = widget.controller.status == AnimationStatus.reverse - ? _masklessColor - : _mask.value; - return Positioned.fromRect( - rect: _rect.value!, - child: ShaderMask( - key: _childGlobalKey, - shaderCallback: (Rect bounds) { - return LinearGradient( - begin: Alignment.topLeft, - end: Alignment.bottomRight, - colors: [color, color], - ).createShader(bounds); - }, - child: widget.child, - ), - ); - } - - @override - Widget build(BuildContext context) { - return Stack( - children: [ - AnimatedBuilder( - builder: _buildAnimation, - animation: widget.controller, - ), - ], - ); - } -} - -// The open CupertinoContextMenu modal. -class _ContextMenuRoute extends PopupRoute { - // Build a _ContextMenuRoute. - _ContextMenuRoute({ - required List actions, - required _ContextMenuLocation contextMenuLocation, - this.barrierLabel, - _ContextMenuPreviewBuilderChildless? builder, - ui.ImageFilter? filter, - required Rect previousChildRect, - RouteSettings? settings, - }) : assert(actions != null && actions.isNotEmpty), - assert(contextMenuLocation != null), - _actions = actions, - _builder = builder, - _contextMenuLocation = contextMenuLocation, - _previousChildRect = previousChildRect, - super( - filter: filter, - settings: settings, - ); - - // Barrier color for a Cupertino modal barrier. - static const Color _kModalBarrierColor = Color(0x6604040F); - - // The duration of the transition used when a modal popup is shown. Eyeballed - // from a physical device running iOS 13.1.2. - static const Duration _kModalPopupTransitionDuration = - Duration(milliseconds: 335); - - final List _actions; - final _ContextMenuPreviewBuilderChildless? _builder; - final GlobalKey _childGlobalKey = GlobalKey(); - final _ContextMenuLocation _contextMenuLocation; - bool _externalOffstage = false; - bool _internalOffstage = false; - Orientation? _lastOrientation; - - // The Rect of the child at the moment that the CupertinoContextMenu opens. - final Rect _previousChildRect; - double? _scale = 1.0; - final GlobalKey _sheetGlobalKey = GlobalKey(); - - static final CurveTween _curve = CurveTween( - curve: Curves.easeOutBack, - ); - static final CurveTween _curveReverse = CurveTween( - curve: Curves.easeInBack, - ); - static final RectTween _rectTween = RectTween(); - static final Animatable _rectAnimatable = _rectTween.chain(_curve); - static final RectTween _rectTweenReverse = RectTween(); - static final Animatable _rectAnimatableReverse = - _rectTweenReverse.chain( - _curveReverse, - ); - static final RectTween _sheetRectTween = RectTween(); - final Animatable _sheetRectAnimatable = _sheetRectTween.chain( - _curve, - ); - final Animatable _sheetRectAnimatableReverse = _sheetRectTween.chain( - _curveReverse, - ); - static final Tween _sheetScaleTween = Tween(); - static final Animatable _sheetScaleAnimatable = - _sheetScaleTween.chain( - _curve, - ); - static final Animatable _sheetScaleAnimatableReverse = - _sheetScaleTween.chain( - _curveReverse, - ); - final Tween _opacityTween = Tween(begin: 0.0, end: 1.0); - late Animation _sheetOpacity; - - @override - final String? barrierLabel; - - @override - Color get barrierColor => _kModalBarrierColor; - - @override - bool get barrierDismissible => true; - - @override - bool get semanticsDismissible => false; - - @override - Duration get transitionDuration => _kModalPopupTransitionDuration; - - // Getting the RenderBox doesn't include the scale from the Transform.scale, - // so it's manually accounted for here. - static Rect _getScaledRect(GlobalKey globalKey, double scale) { - final Rect childRect = _getRect(globalKey); - final Size sizeScaled = childRect.size * scale; - final Offset offsetScaled = Offset( - childRect.left + (childRect.size.width - sizeScaled.width) / 2, - childRect.top + (childRect.size.height - sizeScaled.height) / 2, - ); - return offsetScaled & sizeScaled; - } - - // Get the alignment for the _ContextMenuSheet's Transform.scale based on the - // contextMenuLocation. - static AlignmentDirectional getSheetAlignment( - _ContextMenuLocation contextMenuLocation) { - switch (contextMenuLocation) { - case _ContextMenuLocation.center: - return AlignmentDirectional.topCenter; - case _ContextMenuLocation.right: - return AlignmentDirectional.topEnd; - case _ContextMenuLocation.left: - return AlignmentDirectional.topStart; - } - } - - // The place to start the sheetRect animation from. - static Rect _getSheetRectBegin( - Orientation? orientation, - _ContextMenuLocation contextMenuLocation, - Rect childRect, - Rect sheetRect) { - switch (contextMenuLocation) { - case _ContextMenuLocation.center: - final Offset target = orientation == Orientation.portrait - ? childRect.bottomCenter - : childRect.topCenter; - final Offset centered = target - Offset(sheetRect.width / 2, 0.0); - return centered & sheetRect.size; - case _ContextMenuLocation.right: - final Offset target = orientation == Orientation.portrait - ? childRect.bottomRight - : childRect.topRight; - return (target - Offset(sheetRect.width, 0.0)) & sheetRect.size; - case _ContextMenuLocation.left: - final Offset target = orientation == Orientation.portrait - ? childRect.bottomLeft - : childRect.topLeft; - return target & sheetRect.size; - } - } - - void _onDismiss(BuildContext context, double scale, double opacity) { - _scale = scale; - _opacityTween.end = opacity; - _sheetOpacity = _opacityTween.animate(CurvedAnimation( - parent: animation!, - curve: const Interval(0.9, 1.0), - )); - Navigator.of(context).pop(); - } - - // Take measurements on the child and _ContextMenuSheet and update the - // animation tweens to match. - void _updateTweenRects() { - final Rect childRect = _scale == null - ? _getRect(_childGlobalKey) - : _getScaledRect(_childGlobalKey, _scale!); - _rectTween.begin = _previousChildRect; - _rectTween.end = childRect; - - // When opening, the transition happens from the end of the child's bounce - // animation to the final state. When closing, it goes from the final state - // to the original position before the bounce. - final Rect childRectOriginal = Rect.fromCenter( - center: _previousChildRect.center, - width: _previousChildRect.width / _kOpenScale, - height: _previousChildRect.height / _kOpenScale, - ); - - final Rect sheetRect = _getRect(_sheetGlobalKey); - final Rect sheetRectBegin = _getSheetRectBegin( - _lastOrientation, - _contextMenuLocation, - childRectOriginal, - sheetRect, - ); - _sheetRectTween.begin = sheetRectBegin; - _sheetRectTween.end = sheetRect; - _sheetScaleTween.begin = 0.0; - _sheetScaleTween.end = _scale; - - _rectTweenReverse.begin = childRectOriginal; - _rectTweenReverse.end = childRect; - } - - void _setOffstageInternally() { - super.offstage = _externalOffstage || _internalOffstage; - // It's necessary to call changedInternalState to get the backdrop to - // update. - changedInternalState(); - } - - @override - bool didPop(T? result) { - _updateTweenRects(); - return super.didPop(result); - } - - @override - set offstage(bool value) { - _externalOffstage = value; - _setOffstageInternally(); - } - - @override - TickerFuture didPush() { - _internalOffstage = true; - _setOffstageInternally(); - - // Render one frame offstage in the final position so that we can take - // measurements of its layout and then animate to them. - SchedulerBinding.instance!.addPostFrameCallback((Duration _) { - _updateTweenRects(); - _internalOffstage = false; - _setOffstageInternally(); - }); - return super.didPush(); - } - - @override - Animation createAnimation() { - final Animation animation = super.createAnimation(); - _sheetOpacity = _opacityTween.animate(CurvedAnimation( - parent: animation, - curve: Curves.linear, - )); - return animation; - } - - @override - Widget buildPage(BuildContext context, Animation animation, - Animation secondaryAnimation) { - // This is usually used to build the "page", which is then passed to - // buildTransitions as child, the idea being that buildTransitions will - // animate the entire page into the scene. In the case of _ContextMenuRoute, - // two individual pieces of the page are animated into the scene in - // buildTransitions, and a Container is returned here. - return Container(); - } - - @override - Widget buildTransitions(BuildContext context, Animation animation, - Animation secondaryAnimation, Widget child) { - return OrientationBuilder( - builder: (BuildContext context, Orientation orientation) { - _lastOrientation = orientation; - - // While the animation is running, render everything in a Stack so that - // they're movable. - if (!animation.isCompleted) { - final bool reverse = animation.status == AnimationStatus.reverse; - final Rect rect = reverse - ? _rectAnimatableReverse.evaluate(animation)! - : _rectAnimatable.evaluate(animation)!; - final Rect sheetRect = reverse - ? _sheetRectAnimatableReverse.evaluate(animation)! - : _sheetRectAnimatable.evaluate(animation)!; - final double sheetScale = reverse - ? _sheetScaleAnimatableReverse.evaluate(animation) - : _sheetScaleAnimatable.evaluate(animation); - return Stack( - children: [ - Positioned.fromRect( - rect: sheetRect, - child: FadeTransition( - opacity: _sheetOpacity, - child: Transform.scale( - alignment: getSheetAlignment(_contextMenuLocation), - scale: sheetScale, - child: _ContextMenuSheet( - key: _sheetGlobalKey, - actions: _actions, - contextMenuLocation: _contextMenuLocation, - orientation: orientation, - ), - ), - ), - ), - Positioned.fromRect( - key: _childGlobalKey, - rect: rect, - child: _builder!(context, animation), - ), - ], - ); - } - - // When the animation is done, just render everything in a static layout - // in the final position. - return _ContextMenuRouteStatic( - actions: _actions, - childGlobalKey: _childGlobalKey, - contextMenuLocation: _contextMenuLocation, - onDismiss: _onDismiss, - orientation: orientation, - sheetGlobalKey: _sheetGlobalKey, - child: _builder!(context, animation), - ); - }, - ); - } -} - -// The final state of the _ContextMenuRoute after animating in and before -// animating out. -class _ContextMenuRouteStatic extends StatefulWidget { - const _ContextMenuRouteStatic({ - Key? key, - this.actions, - required this.child, - this.childGlobalKey, - required this.contextMenuLocation, - this.onDismiss, - required this.orientation, - this.sheetGlobalKey, - }) : assert(contextMenuLocation != null), - assert(orientation != null), - super(key: key); - - final List? actions; - final Widget child; - final GlobalKey? childGlobalKey; - final _ContextMenuLocation contextMenuLocation; - final _DismissCallback? onDismiss; - final Orientation orientation; - final GlobalKey? sheetGlobalKey; - - @override - _ContextMenuRouteStaticState createState() => _ContextMenuRouteStaticState(); -} - -class _ContextMenuRouteStaticState extends State<_ContextMenuRouteStatic> - with TickerProviderStateMixin { - // The child is scaled down as it is dragged down until it hits this minimum - // value. - static const double _kMinScale = 0.8; - - // The CupertinoContextMenuSheet disappears at this scale. - static const double _kSheetScaleThreshold = 0.9; - static const double _kPadding = 20.0; - static const double _kDamping = 400.0; - static const Duration _kMoveControllerDuration = Duration(milliseconds: 600); - - late Offset _dragOffset; - double _lastScale = 1.0; - late AnimationController _moveController; - late AnimationController _sheetController; - late Animation _moveAnimation; - late Animation _sheetScaleAnimation; - late Animation _sheetOpacityAnimation; - - // The scale of the child changes as a function of the distance it is dragged. - static double _getScale( - Orientation orientation, double maxDragDistance, double dy) { - final double dyDirectional = dy <= 0.0 ? dy : -dy; - return math.max( - _kMinScale, - (maxDragDistance + dyDirectional) / maxDragDistance, - ); - } - - void _onPanStart(DragStartDetails details) { - _moveController.value = 1.0; - _setDragOffset(Offset.zero); - } - - void _onPanUpdate(DragUpdateDetails details) { - _setDragOffset(_dragOffset + details.delta); - } - - void _onPanEnd(DragEndDetails details) { - // If flung, animate a bit before handling the potential dismiss. - if (details.velocity.pixelsPerSecond.dy.abs() >= kMinFlingVelocity) { - final bool flingIsAway = details.velocity.pixelsPerSecond.dy > 0; - final double finalPosition = - flingIsAway ? _moveAnimation.value.dy + 100.0 : 0.0; - - if (flingIsAway && _sheetController.status != AnimationStatus.forward) { - _sheetController.forward(); - } else if (!flingIsAway && - _sheetController.status != AnimationStatus.reverse) { - _sheetController.reverse(); - } - - _moveAnimation = Tween( - begin: Offset(0.0, _moveAnimation.value.dy), - end: Offset(0.0, finalPosition), - ).animate(_moveController); - _moveController.reset(); - _moveController.duration = const Duration( - milliseconds: 64, - ); - _moveController.forward(); - _moveController.addStatusListener(_flingStatusListener); - return; - } - - // Dismiss if the drag is enough to scale down all the way. - if (_lastScale == _kMinScale) { - widget.onDismiss!(context, _lastScale, _sheetOpacityAnimation.value); - return; - } - - // Otherwise animate back home. - _moveController.addListener(_moveListener); - _moveController.reverse(); - } - - void _moveListener() { - // When the scale passes the threshold, animate the sheet back in. - if (_lastScale > _kSheetScaleThreshold) { - _moveController.removeListener(_moveListener); - if (_sheetController.status != AnimationStatus.dismissed) { - _sheetController.reverse(); - } - } - } - - void _flingStatusListener(AnimationStatus status) { - if (status != AnimationStatus.completed) { - return; - } - - // Reset the duration back to its original value. - _moveController.duration = _kMoveControllerDuration; - - _moveController.removeStatusListener(_flingStatusListener); - // If it was a fling back to the start, it has reset itself, and it should - // not be dismissed. - if (_moveAnimation.value.dy == 0.0) { - return; - } - widget.onDismiss!(context, _lastScale, _sheetOpacityAnimation.value); - } - - Alignment _getChildAlignment( - Orientation orientation, _ContextMenuLocation contextMenuLocation) { - switch (contextMenuLocation) { - case _ContextMenuLocation.center: - return orientation == Orientation.portrait - ? Alignment.bottomCenter - : Alignment.topRight; - case _ContextMenuLocation.right: - return orientation == Orientation.portrait - ? Alignment.bottomCenter - : Alignment.topLeft; - case _ContextMenuLocation.left: - return orientation == Orientation.portrait - ? Alignment.bottomCenter - : Alignment.topRight; - } - } - - void _setDragOffset(Offset dragOffset) { - // Allow horizontal and negative vertical movement, but damp it. - final double endX = _kPadding * dragOffset.dx / _kDamping; - final double endY = dragOffset.dy >= 0.0 - ? dragOffset.dy - : _kPadding * dragOffset.dy / _kDamping; - setState(() { - _dragOffset = dragOffset; - _moveAnimation = Tween( - begin: Offset.zero, - end: Offset( - endX.clamp(-_kPadding, _kPadding), - endY, - ), - ).animate( - CurvedAnimation( - parent: _moveController, - curve: Curves.elasticIn, - ), - ); - - // Fade the _ContextMenuSheet out or in, if needed. - if (_lastScale <= _kSheetScaleThreshold && - _sheetController.status != AnimationStatus.forward && - _sheetScaleAnimation.value != 0.0) { - _sheetController.forward(); - } else if (_lastScale > _kSheetScaleThreshold && - _sheetController.status != AnimationStatus.reverse && - _sheetScaleAnimation.value != 1.0) { - _sheetController.reverse(); - } - }); - } - - // The order and alignment of the _ContextMenuSheet and the child depend on - // both the orientation of the screen as well as the position on the screen of - // the original child. - List _getChildren( - Orientation orientation, _ContextMenuLocation contextMenuLocation) { - final Expanded child = Expanded( - child: Align( - alignment: _getChildAlignment( - widget.orientation, - widget.contextMenuLocation, - ), - child: AnimatedBuilder( - animation: _moveController, - builder: _buildChildAnimation, - child: widget.child, - ), - ), - ); - const SizedBox spacer = SizedBox( - width: _kPadding, - height: _kPadding, - ); - final Expanded sheet = Expanded( - child: AnimatedBuilder( - animation: _sheetController, - builder: _buildSheetAnimation, - child: _ContextMenuSheet( - key: widget.sheetGlobalKey, - actions: widget.actions!, - contextMenuLocation: widget.contextMenuLocation, - orientation: widget.orientation, - ), - ), - ); - - switch (contextMenuLocation) { - case _ContextMenuLocation.center: - return [child, spacer, sheet]; - case _ContextMenuLocation.right: - return orientation == Orientation.portrait - ? [child, spacer, sheet] - : [sheet, spacer, child]; - case _ContextMenuLocation.left: - return [child, spacer, sheet]; - } - } - - // Build the animation for the _ContextMenuSheet. - Widget _buildSheetAnimation(BuildContext context, Widget? child) { - return Transform.scale( - alignment: - _ContextMenuRoute.getSheetAlignment(widget.contextMenuLocation), - scale: _sheetScaleAnimation.value, - child: FadeTransition( - opacity: _sheetOpacityAnimation, - child: child, - ), - ); - } - - // Build the animation for the child. - Widget _buildChildAnimation(BuildContext context, Widget? child) { - _lastScale = _getScale( - widget.orientation, - MediaQuery.of(context).size.height, - _moveAnimation.value.dy, - ); - return Transform.scale( - key: widget.childGlobalKey, - scale: _lastScale, - child: child, - ); - } - - // Build the animation for the overall draggable dismissible content. - Widget _buildAnimation(BuildContext context, Widget? child) { - return Transform.translate( - offset: _moveAnimation.value, - child: child, - ); - } - - @override - void initState() { - super.initState(); - _moveController = AnimationController( - duration: _kMoveControllerDuration, - value: 1.0, - vsync: this, - ); - _sheetController = AnimationController( - duration: const Duration(milliseconds: 100), - reverseDuration: const Duration(milliseconds: 300), - vsync: this, - ); - _sheetScaleAnimation = Tween( - begin: 1.0, - end: 0.0, - ).animate( - CurvedAnimation( - parent: _sheetController, - curve: Curves.linear, - reverseCurve: Curves.easeInBack, - ), - ); - _sheetOpacityAnimation = Tween( - begin: 1.0, - end: 0.0, - ).animate(_sheetController); - _setDragOffset(Offset.zero); - } - - @override - void dispose() { - _moveController.dispose(); - _sheetController.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final List children = _getChildren( - widget.orientation, - widget.contextMenuLocation, - ); - - return SafeArea( - child: Padding( - padding: const EdgeInsets.all(_kPadding), - child: Align( - alignment: Alignment.topLeft, - child: GestureDetector( - onPanEnd: _onPanEnd, - onPanStart: _onPanStart, - onPanUpdate: _onPanUpdate, - child: AnimatedBuilder( - animation: _moveController, - builder: _buildAnimation, - child: widget.orientation == Orientation.portrait - ? Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: children, - ) - : Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: children, - ), - ), - ), - ), - ), - ); - } -} - -// The menu that displays when CupertinoContextMenu is open. It consists of a -// list of actions that are typically CupertinoContextMenuActions. -class _ContextMenuSheet extends StatelessWidget { - _ContextMenuSheet({ - Key? key, - required this.actions, - required _ContextMenuLocation contextMenuLocation, - required Orientation orientation, - }) : assert(actions != null && actions.isNotEmpty), - assert(contextMenuLocation != null), - assert(orientation != null), - _contextMenuLocation = contextMenuLocation, - _orientation = orientation, - super(key: key); - - final List actions; - final _ContextMenuLocation _contextMenuLocation; - final Orientation _orientation; - - // Get the children, whose order depends on orientation and - // contextMenuLocation. - List get children { - final Flexible menu = Flexible( - fit: FlexFit.tight, - flex: 2, - child: IntrinsicHeight( - child: ClipRRect( - borderRadius: const BorderRadius.all(Radius.circular(13.0)), - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: actions, - ), - ), - ), - ); - - switch (_contextMenuLocation) { - case _ContextMenuLocation.center: - return _orientation == Orientation.portrait - ? [ - const Spacer(), - menu, - const Spacer(), - ] - : [ - menu, - const Spacer(), - ]; - case _ContextMenuLocation.right: - return [ - const Spacer(), - menu, - ]; - case _ContextMenuLocation.left: - return [ - menu, - const Spacer(), - ]; - } - } - - @override - Widget build(BuildContext context) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: children, - ); - } -} - -// An animation that switches between two colors. -// -// The transition is immediate, so there are no intermediate values or -// interpolation. The color switches from offColor to onColor and back to -// offColor at the times given by intervalOn and intervalOff. -class _OnOffAnimation extends CompoundAnimation { - _OnOffAnimation({ - required AnimationController controller, - required T onValue, - required T offValue, - required double intervalOn, - required double intervalOff, - }) : _offValue = offValue, - assert(intervalOn >= 0.0 && intervalOn <= 1.0), - assert(intervalOff >= 0.0 && intervalOff <= 1.0), - assert(intervalOn <= intervalOff), - super( - first: Tween(begin: offValue, end: onValue).animate( - CurvedAnimation( - parent: controller, - curve: Interval(intervalOn, intervalOn), - ), - ), - next: Tween(begin: onValue, end: offValue).animate( - CurvedAnimation( - parent: controller, - curve: Interval(intervalOff, intervalOff), - ), - ), - ); - - final T _offValue; - - @override - T get value => next.value == _offValue ? next.value : first.value; -} diff --git a/lib/base/ui/search_cell.dart b/lib/base/ui/search_cell.dart deleted file mode 100644 index 122627b..0000000 --- a/lib/base/ui/search_cell.dart +++ /dev/null @@ -1,66 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; - -import '../theme.dart'; - -class SearchCell extends ConsumerStatefulWidget { - final TextEditingController controller; - - const SearchCell({ - Key? key, - required this.controller, - }) : super(key: key); - - @override - ConsumerState createState() => _SearchCellState(); -} - -class _SearchCellState extends ConsumerState { - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - return CupertinoSearchTextField( - decoration: BoxDecoration( - color: ref.watch(themeProvider).themeColor.blackAndWhite(), - border: Border.all(width: 1, color: const Color(0xffC0C4CC)), - borderRadius: BorderRadius.circular( - 7, - ), - ), - onSuffixTap: () { - widget.controller.text = ""; - setState(() {}); - }, - controller: widget.controller, - padding: const EdgeInsets.symmetric( - horizontal: 5, - vertical: 5, - ), - suffixInsets: const EdgeInsets.only( - right: 15, - ), - prefixIcon: Image.asset( - "assets/images/icon_search.png", - width: 18, - fit: BoxFit.cover, - ), - prefixInsets: const EdgeInsets.only( - left: 10, - top: 2, - ), - placeholderStyle: TextStyle( - fontSize: 14, - color: ref.watch(themeProvider).themeColor.descColor(), - ), - style: const TextStyle( - fontSize: 16, - ), - placeholder: "请输入内容", - ); - } -} diff --git a/lib/base/ui/source_code_view.dart b/lib/base/ui/source_code_view.dart deleted file mode 100644 index 4c41ab1..0000000 --- a/lib/base/ui/source_code_view.dart +++ /dev/null @@ -1,169 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_speed_dial/flutter_speed_dial.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:url_launcher/url_launcher.dart' as url_launcher; -import 'syntax_highlighter.dart'; - -class SourceCodeView extends StatefulWidget { - final String filePath; - final String? codeLinkPrefix; - final bool showLabelText; - final Color? iconBackgroundColor; - final Color? iconForegroundColor; - final Color? labelBackgroundColor; - final TextStyle? labelTextStyle; - final SyntaxHighlighterStyle? syntaxHighlighterStyle; - - const SourceCodeView({ - Key? key, - required this.filePath, - this.codeLinkPrefix, - this.showLabelText = false, - this.iconBackgroundColor, - this.iconForegroundColor, - this.labelBackgroundColor, - this.labelTextStyle, - this.syntaxHighlighterStyle, - }) : super(key: key); - - String? get codeLink => - codeLinkPrefix == null ? null : '$codeLinkPrefix/$filePath'; - - @override - _SourceCodeViewState createState() { - return _SourceCodeViewState(); - } -} - -class _SourceCodeViewState extends State { - double _textScaleFactor = 1.0; - - Widget _getCodeView(String codeContent, BuildContext context) { - codeContent = codeContent.replaceAll('\r\n', '\n'); - final SyntaxHighlighterStyle style = widget.syntaxHighlighterStyle ?? - (Theme.of(context).brightness == Brightness.dark - ? SyntaxHighlighterStyle.darkThemeStyle() - : SyntaxHighlighterStyle.lightThemeStyle()); - return Container( - constraints: BoxConstraints.expand(), - child: Scrollbar( - child: SingleChildScrollView( - child: SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: SelectableText.rich( - TextSpan( - style: GoogleFonts.droidSansMono(fontSize: 12) - .apply(fontSizeFactor: this._textScaleFactor), - children: [ - DartSyntaxHighlighter(style).format(codeContent) - ], - ), - style: DefaultTextStyle.of(context) - .style - .apply(fontSizeFactor: this._textScaleFactor), - ), - ), - ), - ), - ); - } - - List _buildFloatingButtons({ - TextStyle? labelTextStyle, - Color? iconBackgroundColor, - Color? iconForegroundColor, - Color? labelBackgroundColor, - required bool showLabelText, - }) => - [ - if (this.widget.codeLink != null) - SpeedDialChild( - child: Icon(Icons.content_copy), - labelWidget: showLabelText ? Text('Copy code to clipboard') : null, - backgroundColor: iconBackgroundColor, - foregroundColor: iconForegroundColor, - labelBackgroundColor: labelBackgroundColor, - labelStyle: labelTextStyle, - onTap: () async { - Clipboard.setData(ClipboardData( - text: await DefaultAssetBundle.of(context) - .loadString(widget.filePath))); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text('Code copied to clipboard!'), - )); - }, - ), - if (this.widget.codeLink != null) - SpeedDialChild( - child: Icon(Icons.open_in_new), - labelWidget: showLabelText ? Text('View code in browser') : null, - backgroundColor: iconBackgroundColor, - foregroundColor: iconForegroundColor, - labelBackgroundColor: labelBackgroundColor, - labelStyle: labelTextStyle, - onTap: () => url_launcher.launch(this.widget.codeLink!), - ), - SpeedDialChild( - child: Icon(Icons.zoom_out), - label: showLabelText ? 'Zoom out' : null, - // labelWidget: showLabelText ? Text('Zoom out') : null, - backgroundColor: iconBackgroundColor, - foregroundColor: iconForegroundColor, - labelBackgroundColor: labelBackgroundColor, - labelStyle: labelTextStyle, - onTap: () => setState(() { - this._textScaleFactor = max(0.8, this._textScaleFactor - 0.1); - }), - ), - SpeedDialChild( - child: Icon(Icons.zoom_in), - labelWidget: showLabelText ? Text('Zoom in') : null, - backgroundColor: iconBackgroundColor, - foregroundColor: iconForegroundColor, - labelBackgroundColor: labelBackgroundColor, - labelStyle: labelTextStyle, - onTap: () => setState(() { - this._textScaleFactor += 0.1; - }), - ), - ]; - - @override - Widget build(BuildContext context) { - return FutureBuilder( - future: DefaultAssetBundle.of(context).loadString(widget.filePath), - builder: (BuildContext context, AsyncSnapshot snapshot) { - if (snapshot.hasData) { - return Scaffold( - body: Padding( - padding: EdgeInsets.all(4.0), - child: _getCodeView(snapshot.data!, context), - ), - floatingActionButton: SpeedDial( - renderOverlay: false, - overlayOpacity: 0, - children: _buildFloatingButtons( - labelTextStyle: widget.labelTextStyle, - iconBackgroundColor: widget.iconBackgroundColor, - iconForegroundColor: widget.iconForegroundColor, - labelBackgroundColor: widget.labelBackgroundColor, - showLabelText: widget.showLabelText, - ), - backgroundColor: Colors.blue, - foregroundColor: Colors.white, - activeBackgroundColor: Colors.red, - activeForegroundColor: Colors.white, - icon: Icons.menu, - activeIcon: Icons.close, - ), - ); - } else { - return Center(child: CircularProgressIndicator()); - } - }, - ); - } -} diff --git a/lib/base/ui/syntax_highlighter.dart b/lib/base/ui/syntax_highlighter.dart deleted file mode 100644 index 7c375dd..0000000 --- a/lib/base/ui/syntax_highlighter.dart +++ /dev/null @@ -1,387 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'package:flutter/material.dart'; -import 'package:string_scanner/string_scanner.dart'; - -class SyntaxHighlighterStyle { - SyntaxHighlighterStyle( - {this.baseStyle, - this.numberStyle, - this.commentStyle, - this.keywordStyle, - this.stringStyle, - this.punctuationStyle, - this.classStyle, - this.constantStyle}); - - static SyntaxHighlighterStyle lightThemeStyle() => SyntaxHighlighterStyle( - baseStyle: const TextStyle( - color: const Color(0xFF000000), - height: 1, - ), - numberStyle: const TextStyle(color: const Color(0xFF1565C0)), - commentStyle: const TextStyle(color: const Color(0xFF9E9E9E)), - keywordStyle: const TextStyle(color: const Color(0xFF9C27B0)), - stringStyle: const TextStyle(color: const Color(0xFF43A047)), - punctuationStyle: const TextStyle(color: const Color(0xFF000000)), - classStyle: const TextStyle(color: const Color(0xFF512DA8)), - constantStyle: const TextStyle(color: const Color(0xFF795548)), - ); - - static SyntaxHighlighterStyle darkThemeStyle() => SyntaxHighlighterStyle( - baseStyle: const TextStyle(color: const Color(0xFFFFFFFF)), - numberStyle: const TextStyle(color: const Color(0xFF1565C0)), - commentStyle: const TextStyle(color: const Color(0xFF9E9E9E)), - keywordStyle: const TextStyle(color: const Color(0xFF80CBC4)), - stringStyle: const TextStyle(color: const Color(0xFF009688)), - punctuationStyle: const TextStyle(color: const Color(0xFFFFFFFF)), - classStyle: const TextStyle(color: const Color(0xFF009688)), - constantStyle: const TextStyle(color: const Color(0xFF795548)), - ); - - SyntaxHighlighterStyle copyWith({ - TextStyle? baseStyle, - TextStyle? numberStyle, - TextStyle? commentStyle, - TextStyle? keywordStyle, - TextStyle? stringStyle, - TextStyle? punctuationStyle, - TextStyle? classStyle, - TextStyle? constantStyle, - }) => - SyntaxHighlighterStyle( - baseStyle: baseStyle ?? this.baseStyle, - numberStyle: numberStyle ?? this.numberStyle, - commentStyle: commentStyle ?? this.commentStyle, - keywordStyle: keywordStyle ?? this.keywordStyle, - stringStyle: stringStyle ?? this.stringStyle, - punctuationStyle: punctuationStyle ?? this.punctuationStyle, - classStyle: classStyle ?? this.classStyle, - constantStyle: constantStyle ?? this.constantStyle, - ); - - final TextStyle? baseStyle; - final TextStyle? numberStyle; - final TextStyle? commentStyle; - final TextStyle? keywordStyle; - final TextStyle? stringStyle; - final TextStyle? punctuationStyle; - final TextStyle? classStyle; - final TextStyle? constantStyle; -} - -abstract class SyntaxHighlighter { - // ignore: one_member_abstracts - TextSpan format(String src); -} - -class DartSyntaxHighlighter extends SyntaxHighlighter { - DartSyntaxHighlighter([this._style]) { - _spans = <_HighlightSpan>[]; - _style ??= SyntaxHighlighterStyle.darkThemeStyle(); - } - - SyntaxHighlighterStyle? _style; - - static const List _keywords = const [ - 'abstract', - 'as', - 'assert', - 'async', - 'await', - 'break', - 'case', - 'catch', - 'class', - 'const', - 'continue', - 'default', - 'deferred', - 'do', - 'dynamic', - 'else', - 'enum', - 'export', - 'external', - 'extends', - 'factory', - 'false', - 'final', - 'finally', - 'for', - 'get', - 'if', - 'implements', - 'import', - 'in', - 'is', - 'library', - 'new', - 'null', - 'operator', - 'part', - 'rethrow', - 'return', - 'set', - 'static', - 'super', - 'switch', - 'sync', - 'this', - 'throw', - 'true', - 'try', - 'typedef', - 'var', - 'void', - 'while', - 'with', - 'yield' - ]; - - static const List _builtInTypes = const [ - 'int', - 'double', - 'num', - 'bool' - ]; - - late String _src; - late StringScanner _scanner; - - late List<_HighlightSpan> _spans; - - @override - TextSpan format(String src) { - _src = src; - _scanner = StringScanner(_src); - - if (_generateSpans()) { - // Successfully parsed the code - final List formattedText = []; - int currentPosition = 0; - - for (_HighlightSpan span in _spans) { - if (currentPosition != span.start) - formattedText - .add(TextSpan(text: _src.substring(currentPosition, span.start))); - - formattedText.add(TextSpan( - style: span.textStyle(_style), text: span.textForSpan(_src))); - - currentPosition = span.end; - } - - if (currentPosition != _src.length) - formattedText - .add(TextSpan(text: _src.substring(currentPosition, _src.length))); - - return TextSpan(style: _style!.baseStyle, children: formattedText); - } else { - // Parsing failed, return with only basic formatting - return TextSpan(style: _style!.baseStyle, text: src); - } - } - - bool _generateSpans() { - int lastLoopPosition = _scanner.position; - - while (!_scanner.isDone) { - // Skip White space - _scanner.scan(RegExp(r'\s+')); - - // Block comments - if (_scanner.scan(RegExp(r'/\*(.|\n)*\*/'))) { - _spans.add(_HighlightSpan(_HighlightType.comment, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Line comments - if (_scanner.scan('##')) { - final int startComment = _scanner.lastMatch!.start; - - bool eof = false; - int endComment; - if (_scanner.scan(RegExp(r'.*\n'))) { - endComment = _scanner.lastMatch!.end - 1; - } else { - eof = true; - endComment = _src.length; - } - - _spans.add( - _HighlightSpan(_HighlightType.comment, startComment, endComment)); - - if (eof) break; - - continue; - } - - // Raw r"String" - if (_scanner.scan(RegExp(r'r".*"'))) { - _spans.add(_HighlightSpan(_HighlightType.string, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Raw r'String' - if (_scanner.scan(RegExp(r"r'.*'"))) { - _spans.add(_HighlightSpan(_HighlightType.string, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Multiline """String""" - if (_scanner.scan(RegExp(r'"""(?:[^"\\]|\\(.|\n))*"""'))) { - _spans.add(_HighlightSpan(_HighlightType.string, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Multiline '''String''' - if (_scanner.scan(RegExp(r"'''(?:[^'\\]|\\(.|\n))*'''"))) { - _spans.add(_HighlightSpan(_HighlightType.string, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // "String" - if (_scanner.scan(RegExp(r'"(?:[^"\\]|\\.)*"'))) { - _spans.add(_HighlightSpan(_HighlightType.string, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // 'String' - if (_scanner.scan(RegExp(r"'(?:[^'\\]|\\.)*'"))) { - _spans.add(_HighlightSpan(_HighlightType.string, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Double - if (_scanner.scan(RegExp(r'\d+\.\d+'))) { - _spans.add(_HighlightSpan(_HighlightType.number, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Integer - if (_scanner.scan(RegExp(r'\d+'))) { - _spans.add(_HighlightSpan(_HighlightType.number, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Punctuation - if (_scanner.scan(RegExp(r'[\[\]{}().!=<>&\|\?\+\-\*/%\^~;:,]'))) { - _spans.add(_HighlightSpan(_HighlightType.punctuation, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Meta data - if (_scanner.scan(RegExp(r'@\w+'))) { - _spans.add(_HighlightSpan(_HighlightType.keyword, - _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - continue; - } - - // Words - if (_scanner.scan(RegExp(r'\w+'))) { - _HighlightType? type; - - String word = _scanner.lastMatch![0]!; - if (word.startsWith('_')) word = word.substring(1); - - if (_keywords.contains(word)) - type = _HighlightType.keyword; - else if (_builtInTypes.contains(word)) - type = _HighlightType.keyword; - else if (_firstLetterIsUpperCase(word)) - type = _HighlightType.klass; - else if (word.length >= 2 && - word.startsWith('k') && - _firstLetterIsUpperCase(word.substring(1))) - type = _HighlightType.constant; - - if (type != null) { - _spans.add(_HighlightSpan( - type, _scanner.lastMatch!.start, _scanner.lastMatch!.end)); - } - } - - // Check if this loop did anything - if (lastLoopPosition == _scanner.position) { - // Failed to parse this file, abort gracefully - return false; - } - lastLoopPosition = _scanner.position; - } - - _simplify(); - return true; - } - - void _simplify() { - for (int i = _spans.length - 2; i >= 0; i -= 1) { - if (_spans[i].type == _spans[i + 1].type && - _spans[i].end == _spans[i + 1].start) { - _spans[i] = - _HighlightSpan(_spans[i].type, _spans[i].start, _spans[i + 1].end); - _spans.removeAt(i + 1); - } - } - } - - bool _firstLetterIsUpperCase(String str) { - if (str.isNotEmpty) { - final String first = str.substring(0, 1); - return first == first.toUpperCase(); - } - return false; - } -} - -enum _HighlightType { - number, - comment, - keyword, - string, - punctuation, - klass, - constant -} - -class _HighlightSpan { - _HighlightSpan(this.type, this.start, this.end); - final _HighlightType type; - final int start; - final int end; - - String textForSpan(String src) { - return src.substring(start, end); - } - - TextStyle? textStyle(SyntaxHighlighterStyle? style) { - if (type == _HighlightType.number) - return style!.numberStyle; - else if (type == _HighlightType.comment) - return style!.commentStyle; - else if (type == _HighlightType.keyword) - return style!.keywordStyle; - else if (type == _HighlightType.string) - return style!.stringStyle; - else if (type == _HighlightType.punctuation) - return style!.punctuationStyle; - else if (type == _HighlightType.klass) - return style!.classStyle; - else if (type == _HighlightType.constant) - return style!.constantStyle; - else - return style!.baseStyle; - } -} diff --git a/lib/base/userinfo_viewmodel.dart b/lib/base/userinfo_viewmodel.dart deleted file mode 100644 index 7b92fc9..0000000 --- a/lib/base/userinfo_viewmodel.dart +++ /dev/null @@ -1,146 +0,0 @@ -import 'dart:convert'; - -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -import '../main.dart'; -import 'sp_const.dart'; -import 'theme.dart'; - -class UserInfoViewModel { - int _primaryColor = commonColor.value; - String? _token; - String? _host = ""; - String? _userName; - String? _passWord; - bool _useSecertLogined = false; - - List historyAccounts = []; - - UserInfoViewModel() { - _token = SpUtil.getString(spUserInfo); - _userName = SpUtil.getString(spUserName); - _passWord = SpUtil.getString(spPassWord); - _primaryColor = SpUtil.getInt(spCustomColor, defValue: commonColor.value); - - _useSecertLogined = SpUtil.getBool(spSecretLogined, defValue: false); - _host = SpUtil.getString(spHost, defValue: ''); - - List? tempList = - jsonDecode(SpUtil.getString(spLoginHistory, defValue: '[]')); - - if (tempList != null && tempList.isNotEmpty) { - for (Map value in tempList) { - historyAccounts.add(UserInfoBean.fromJson(value)); - } - } - } - - void updateToken(String token) { - _token = token; - SpUtil.putString(spUserInfo, token); - } - - void updateUserName( - String host, String userName, String password, bool secretLogin) { - updateHost(host); - _useSecretLogin(secretLogin); - _userName = userName; - _passWord = password; - SpUtil.putString(spUserName, userName); - SpUtil.putString(spPassWord, password); - - save2HistoryAccount(); - } - - void _useSecretLogin(bool use) { - _useSecertLogined = use; - SpUtil.putBool(spSecretLogined, _useSecertLogined); - } - - void updateCustomColor(int color) { - _primaryColor = color; - SpUtil.putInt(spCustomColor, color); - } - - void updateHost(String host) { - _host = host; - SpUtil.putString(spHost, host); - } - - String? get token => _token; - - String? get host => _host; - - String? get userName => _userName; - - String? get passWord => _passWord; - - bool get useSecretLogined => _useSecertLogined; - - int get primaryColor => _primaryColor; - - bool isLogined() { - return token != null && token!.isNotEmpty; - } - - void save2HistoryAccount() { - if (_host == null || _host!.isEmpty) return; - if (_userName == null || _userName!.isEmpty) return; - if (_passWord == null || _passWord!.isEmpty) return; - - //如果已经存在host,那就更新 - - "login success $_host $userName $passWord".log(); - - historyAccounts.removeWhere((element) => element.host == _host); - - historyAccounts.insert( - 0, - UserInfoBean( - userName: _userName, - password: _passWord, - useSecretLogined: _useSecertLogined, - host: _host)); - - while (historyAccounts.length > 3) { - historyAccounts.removeLast(); - } - - SpUtil.putString(spLoginHistory, jsonEncode(historyAccounts)); - } - - void removeHistoryAccount(String? host) { - if (host == null || host.isEmpty) return; - - historyAccounts.removeWhere((element) => element.host == host); - - SpUtil.putString(spLoginHistory, jsonEncode(historyAccounts)); - } -} - -class UserInfoBean { - String? userName; - String? password; - bool useSecretLogined = false; - String? host; - - UserInfoBean( - {this.userName, this.password, this.useSecretLogined = false, this.host}); - - UserInfoBean.fromJson(Map json) { - userName = json['userName']; - password = json['password']; - useSecretLogined = json['useSecretLogined'] ?? false; - host = json['host']; - } - - Map toJson() { - final Map data = new Map(); - data['userName'] = this.userName; - data['password'] = this.password; - data['useSecretLogined'] = this.useSecretLogined; - data['host'] = this.host; - return data; - } -} diff --git a/lib/json.dart b/lib/json.dart deleted file mode 100644 index 7177935..0000000 --- a/lib/json.dart +++ /dev/null @@ -1,4 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -@JsonConversionTarget() -class Json {} diff --git a/lib/json.jc.dart b/lib/json.jc.dart deleted file mode 100644 index cf6c4ca..0000000 --- a/lib/json.jc.dart +++ /dev/null @@ -1,124 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -import 'package:qinglong_app/module/config/config_bean.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/module/home/system_bean.dart'; -import 'package:qinglong_app/module/login/login_bean.dart'; -import 'package:qinglong_app/module/login/user_bean.dart'; -import 'package:qinglong_app/module/others/dependencies/dependency_bean.dart'; -import 'package:qinglong_app/module/others/login_log/login_log_bean.dart'; -import 'package:qinglong_app/module/others/scripts/script_bean.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_bean.dart'; -import 'package:qinglong_app/module/others/task_log/task_log_bean.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; - - -class JsonConversion$Json { - - static M fromJson(dynamic json) { - if (json is List) { - return _getListChildType(json); - } else { - return _fromJsonSingle(json); - } - } - - static M _fromJsonSingle(dynamic json) { - - String type = M.toString(); - - if(type == (ConfigBean).toString()){ - return ConfigBean.jsonConversion(json) as M; - } - - if(type == (EnvBean).toString()){ - return EnvBean.jsonConversion(json) as M; - } - - if(type == (SystemBean).toString()){ - return SystemBean.jsonConversion(json) as M; - } - - if(type == (LoginBean).toString()){ - return LoginBean.jsonConversion(json) as M; - } - - if(type == (UserBean).toString()){ - return UserBean.jsonConversion(json) as M; - } - - if(type == (DependencyBean).toString()){ - return DependencyBean.jsonConversion(json) as M; - } - - if(type == (LoginLogBean).toString()){ - return LoginLogBean.jsonConversion(json) as M; - } - - if(type == (ScriptBean).toString()){ - return ScriptBean.jsonConversion(json) as M; - } - - if(type == (TaskLogBean).toString()){ - return TaskLogBean.jsonConversion(json) as M; - } - - if(type == (TaskBean).toString()){ - return TaskBean.jsonConversion(json) as M; - } - - if (type == (Subscription).toString()){ - return Subscription.fromJson(json) as M; - } - - throw Exception("not found"); - } - - static M _getListChildType(List data) { - if([] is M){ - return data.map((e) => ConfigBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => EnvBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => SystemBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => LoginBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => UserBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => DependencyBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => LoginLogBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => ScriptBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => TaskLogBean.jsonConversion(e)).toList() as M; - } - - if([] is M){ - return data.map((e) => TaskBean.jsonConversion(e)).toList() as M; - } - - if ([] is M){ - return data.map((e) => Subscription.jsonConversion(e)).toList() as M; - } - - throw Exception("not found"); - } -} diff --git a/lib/main.dart b/lib/main.dart deleted file mode 100644 index ed80c37..0000000 --- a/lib/main.dart +++ /dev/null @@ -1,118 +0,0 @@ -import 'dart:io'; - -import 'package:dio_log/overlay_draggable_button.dart'; -import 'package:flutter/foundation.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/scheduler.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:get_it/get_it.dart'; -import 'package:logger/logger.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/module/login/login_page.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:flutter_displaymode/flutter_displaymode.dart'; - -import 'base/routes.dart'; -import 'base/userinfo_viewmodel.dart'; -import 'module/home/home_page.dart'; - -final getIt = GetIt.instance; -var navigatorState = GlobalKey(); - -var logger = Logger(); - -void main() async { - WidgetsFlutterBinding.ensureInitialized(); - await SpUtil.getInstance(); - getIt.registerSingleton(UserInfoViewModel()); - - await SystemChrome.setPreferredOrientations( - [ - DeviceOrientation.portraitUp, - DeviceOrientation.portraitDown, - ], - ); - runApp( - ProviderScope( - overrides: [ - themeProvider, - ], - child: const QlApp(), - ), - ); - if (Platform.isAndroid) { - SystemUiOverlayStyle style = const SystemUiOverlayStyle(statusBarColor: Colors.transparent); - SystemChrome.setSystemUIOverlayStyle(style); - } -} - -class QlApp extends ConsumerStatefulWidget { - const QlApp({Key? key}) : super(key: key); - - @override - ConsumerState createState() => QlAppState(); -} - -class QlAppState extends ConsumerState { - List modes = []; - DisplayMode? active; - DisplayMode? preferred; - - @override - void initState() { - super.initState(); - SchedulerBinding.instance.addPostFrameCallback((_) { - fetchAll(); - }); - } - - Future fetchAll() async { - try { - modes = await FlutterDisplayMode.supported; - modes.forEach(print); - await FlutterDisplayMode.setHighRefreshRate(); - } on PlatformException catch (e) { - print(e); - } - setState(() {}); - } - - @override - Widget build(BuildContext context) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - FocusScope.of(context).requestFocus(FocusNode()); - }, - child: MaterialApp( - title: "青龙", - locale: const Locale('zh', 'CN'), - navigatorKey: navigatorState, - localizationsDelegates: const [ - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - supportedLocales: const [ - Locale('zh', 'CN'), - Locale('en', 'US'), - ], - theme: ref.watch(themeProvider).currentTheme, - onGenerateRoute: (setting) { - return Routes.generateRoute(setting); - }, - home: Builder( - builder: (context) { - if (!kReleaseMode) { - showDebugBtn(context); - } - return getIt().isLogined() ? const HomePage() : const LoginPage(); - }, - ), - // home: LoginPage(), - ), - ); - } -} diff --git a/lib/module/change_account_page.dart b/lib/module/change_account_page.dart deleted file mode 100644 index 87474a1..0000000 --- a/lib/module/change_account_page.dart +++ /dev/null @@ -1,326 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/login_helper.dart'; - -import '../../main.dart'; - -class ChangeAccountPage extends ConsumerStatefulWidget { - const ChangeAccountPage({Key? key}) : super(key: key); - - @override - _ChangeAccountPageState createState() => _ChangeAccountPageState(); -} - -class _ChangeAccountPageState extends ConsumerState { - String isLoginingHost = ""; - String preHost = ""; - - @override - void initState() { - super.initState(); - preHost = getIt().historyAccounts.first.host ?? ""; - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - title: "切换账号", - ), - body: SingleChildScrollView( - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - SizedBox( - height: MediaQuery.of(context).size.height / 10, - ), - Text( - "轻触账号以切换登录", - style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 22, - ), - ), - const SizedBox( - height: 30, - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: ListView.separated( - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - if (index == - getIt().historyAccounts.length) { - return addAccount(); - } - return ClipRRect( - borderRadius: BorderRadius.circular(10), - child: Container( - color: ref - .watch(themeProvider) - .themeColor - .settingBordorColor(), - child: buildCell(index), - ), - ); - }, - separatorBuilder: (_, __) { - return const SizedBox( - height: 10, - ); - }, - itemCount: - getIt().historyAccounts.length + 1), - ), - ], - ), - ), - ), - ); - } - - Widget buildCell(int index) { - Widget child = ListTile( - title: Text( - getIt().historyAccounts[index].host ?? "", - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - contentPadding: const EdgeInsets.symmetric( - horizontal: 15, - ), - minVerticalPadding: 10, - subtitle: Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - getIt().historyAccounts[index].userName ?? "", - ), - ), - trailing: index == 0 - ? Container( - padding: const EdgeInsets.symmetric( - horizontal: 5, - ), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - border: Border.all( - color: ref.watch(themeProvider).primaryColor, width: 1), - ), - child: Text( - "已登录", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, fontSize: 12), - ), - ) - : (isLoginingHost.isNotEmpty - ? SizedBox( - width: 15, - height: 15, - child: CircularProgressIndicator( - strokeWidth: 2, - color: ref.watch(themeProvider).primaryColor, - ), - ) - : const SizedBox.shrink()), - ); - - if (getIt().historyAccounts[index].host == - getIt().host) { - return child; - } - - return Slidable( - key: ValueKey(index), - endActionPane: ActionPane( - motion: const ScrollMotion(), - extentRatio: 0.15, - children: [ - SlidableAction( - backgroundColor: Colors.red, - flex: 1, - onPressed: (_) { - getIt().removeHistoryAccount( - getIt().historyAccounts[index].host); - setState(() {}); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.delete, - ), - ], - ), - child: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - loginNewByBean(getIt().historyAccounts[index]); - }, - child: child), - ); - } - - LoginHelper? helper; - - void loginNewByBean(UserInfoBean historyAccount) async { - isLoginingHost = historyAccount.host ?? ""; - setState(() {}); - helper = LoginHelper( - historyAccount.useSecretLogined, - historyAccount.host ?? "", - historyAccount.userName ?? "", - historyAccount.password ?? "", - true, - ); - var response = await helper!.login(); - dealLoginResponse(response); - } - - void dealLoginResponse(int response) { - if (response == LoginHelper.success) { - Navigator.of(context) - .pushNamedAndRemoveUntil(Routes.routeHomePage, (_) => false); - } else if (response == LoginHelper.failed) { - loginFailed(); - } else { - twoFact(); - } - } - - void loginFailed() { - isLoginingHost = ""; - Http.clear(); - getIt().updateHost(preHost); - setState(() {}); - } - - void twoFact() { - String twoFact = ""; - showCupertinoDialog( - context: context, - builder: (_) => CupertinoAlertDialog( - title: const Text("两步验证"), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Material( - color: Colors.transparent, - child: TextField( - onChanged: (value) { - twoFact = value; - }, - maxLines: 1, - keyboardType: TextInputType.number, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入code", - ), - autofocus: true, - ), - ), - ], - ), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () async { - Navigator.of(context).pop(true); - if (helper != null) { - var response = await helper!.loginTwice(twoFact); - dealLoginResponse(response); - } else { - "状态异常".toast(); - } - }, - ), - ], - )).then((value) { - if (value == null) { - isLoginingHost = ""; - setState(() {}); - } - }); - } - - Widget addAccount() { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamedAndRemoveUntil( - Routes.routeLogin, - (_) => false, - arguments: true, - ); - }, - child: ClipRRect( - borderRadius: BorderRadius.circular(10), - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - horizontal: 15, - ), - decoration: BoxDecoration( - color: ref.watch(themeProvider).themeColor.settingBordorColor(), - borderRadius: BorderRadius.circular(15), - ), - child: Row( - children: [ - Container( - width: 40, - height: 40, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - border: Border.all( - color: ref.watch(themeProvider).themeColor.descColor(), - ), - ), - child: Icon( - CupertinoIcons.add, - color: ref.watch(themeProvider).themeColor.descColor(), - ), - ), - const SizedBox( - width: 15, - ), - Text( - "添加账号", - style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 16, - ), - ), - ], - ), - ), - ), - ); - } -} diff --git a/lib/module/config/config_bean.dart b/lib/module/config/config_bean.dart deleted file mode 100644 index 56396e0..0000000 --- a/lib/module/config/config_bean.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -@JsonConversion() -class ConfigBean { - String? title; - String? value; - - ConfigBean({this.title, this.value}); - - ConfigBean.fromJson(Map json) { - title = json['title']; - value = json['value']; - } - - Map toJson() { - final Map data = new Map(); - data['title'] = this.title; - data['value'] = this.value; - return data; - } - - static ConfigBean jsonConversion(Map json) { - return ConfigBean.fromJson(json); - } -} diff --git a/lib/module/config/config_edit_page.dart b/lib/module/config/config_edit_page.dart deleted file mode 100644 index bfad5f8..0000000 --- a/lib/module/config/config_edit_page.dart +++ /dev/null @@ -1,343 +0,0 @@ -import 'package:code_text_field/code_text_field.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:highlight/languages/powershell.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/sp_const.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -class ConfigEditPage extends ConsumerStatefulWidget { - final String content; - final String title; - - const ConfigEditPage(this.title, this.content, {Key? key}) : super(key: key); - - @override - _ConfigEditPageState createState() => _ConfigEditPageState(); -} - -class _ConfigEditPageState extends ConsumerState { - CodeController? _codeController; - late String result; - late String preResult; - List operateList = []; - - @override - void dispose() { - _codeController?.dispose(); - super.dispose(); - } - - @override - void initState() { - result = widget.content; - preResult = widget.content; - super.initState(); - generateOperateList(); - - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - focusNode.requestFocus(); - checkClipBoard(); - }); - } - - Future notifyICloud( - BuildContext context, String? title, String? content) async {} - - @override - Widget build(BuildContext context) { - _codeController ??= CodeController( - text: result, - language: powershell, - onChange: (value) { - result = value; - }, - theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), - stringMap: { - "export": const TextStyle( - fontWeight: FontWeight.normal, color: Color(0xff6B2375)), - }, - ); - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - FocusManager.instance.primaryFocus?.unfocus(); - - if (preResult == result) { - Navigator.of(context).pop(); - } else { - showCupertinoDialog( - context: context, - useRootNavigator: false, - builder: (childContext) => CupertinoAlertDialog( - title: const Text("温馨提示"), - content: const Text("你编辑的内容还没用提交,确定退出吗?"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(childContext).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () { - Navigator.of(childContext).pop(); - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - } - }, - title: '编辑${widget.title}', - actions: [ - const SizedBox( - width: 15, - ), - Material( - color: Colors.transparent, - child: PopupMenuButton( - onSelected: (String result) { - updateValueBykey(result); - }, - itemBuilder: (BuildContext context) => >[ - ...operateList - .map( - (e) => PopupMenuItem( - child: Text(e), - value: e, - ), - ) - .toList(), - ], - child: const Center( - child: Icon( - CupertinoIcons.arrow_up_right_diamond, - ), - ), - ), - ), - InkWell( - onTap: () async { - HttpResponse response = - await Api.saveFile(widget.title, result); - await notifyICloud(context, widget.title, result); - if (response.success) { - "提交成功".toast(); - Navigator.of(context).pop(widget.title); - } else { - (response.message ?? "").toast(); - } - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, - ), - child: CodeField( - controller: _codeController!, - expands: true, - background: Colors.white, - wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true, - hideColumn: !SpUtil.getBool(spShowLine, defValue: false), - lineNumberStyle: LineNumberStyle( - textStyle: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ), - ), - ); - } - - FocusNode focusNode = FocusNode(); - - void generateOperateList() { - operateList.clear(); - List array = result.split("\n"); - for (String a in array) { - String t = a.replaceAll(" ", ""); - if (t.trim().startsWith("export")) { - int i = t.indexOf("export") + 6; - int j = t.indexOf("="); - operateList.add(t.substring(i, j)); - } - } - } - - void updateValueBykey(String key) async { - String defaultValue = ""; - try { - var clipBoard = await Clipboard.getData(Clipboard.kTextPlain); - - if (clipBoard != null && clipBoard.text != null) { - String tempText = clipBoard.text!; - - if (tempText.trim().contains("export")) { - int i = tempText.trim().indexOf("\""); - int j = tempText.trim().lastIndexOf("\""); - - if (i == -1 || j == -1) { - i = tempText.trim().indexOf("'"); - j = tempText.trim().lastIndexOf("'"); - } - - defaultValue = tempText.trim().substring(i, j); - } else { - defaultValue = tempText; - } - } - } catch (e) {} - - TextEditingController controller = TextEditingController( - text: defaultValue.replaceAll("\"", "").replaceAll("'", "")); - showCupertinoDialog( - useRootNavigator: false, - context: context, - builder: (context) => CupertinoAlertDialog( - title: Text("编辑$key:"), - content: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: TextField( - controller: controller, - decoration: const InputDecoration( - isDense: true, - contentPadding: EdgeInsets.all(4), - hintText: "请输入值", - hintStyle: TextStyle( - fontSize: 14, - ), - ), - autofocus: false, - ), - ), - ], - ), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () async { - Navigator.of(context).pop(); - updateValueByKey(key, controller.text); - }, - ), - ], - ), - ); - } - - void updateValueByKey(String key, String text) { - List array = result.split("\n"); - for (String a in array) { - String t = a.replaceAll(" ", ""); - if (t.trim().startsWith("export")) { - int i = t.indexOf("export") + 6; - int j = t.indexOf("="); - - String tempResult = t.substring(i, j); - if (tempResult == key) { - result = result.replaceAll(a, "\nexport $key = \"$text\" \n\n"); - break; - } - } - } - _codeController = null; - setState(() {}); - "已修改".toast(); - } - - void checkClipBoard() async { - try { - String key = ""; - String value = ""; - var clipBoard = await Clipboard.getData(Clipboard.kTextPlain); - - if (clipBoard != null && clipBoard.text != null) { - String tempText = clipBoard.text!; - - if (tempText.trim().contains("export")) { - int kI = tempText.trim().indexOf("export"); - int kJ = tempText.trim().indexOf("="); - - key = tempText.trim().substring(kI + 6, kJ); - - int i = tempText.trim().indexOf("\""); - int j = tempText.trim().lastIndexOf("\""); - - if (i == -1 || j == -1) { - i = tempText.trim().indexOf("'"); - j = tempText.trim().lastIndexOf("'"); - } - value = tempText.trim().substring(i, j); - - if (key.isNotEmpty && result.contains(key) && value.isNotEmpty) { - WidgetsBinding.instance.endOfFrame.then((value) { - updateValueBykey(key); - }); - } - } - } - } catch (e) {} - } -} diff --git a/lib/module/config/config_page.dart b/lib/module/config/config_page.dart deleted file mode 100644 index e6b38ee..0000000 --- a/lib/module/config/config_page.dart +++ /dev/null @@ -1,184 +0,0 @@ -import 'dart:ui'; - -import 'package:code_text_field/code_text_field.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:highlight/languages/powershell.dart'; -import 'package:qinglong_app/base/base_state_widget.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/sp_const.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/abs_underline_tabindicator.dart'; -import 'package:qinglong_app/base/ui/empty_widget.dart'; -import 'package:qinglong_app/main.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -import '../../base/ui/syntax_highlighter.dart'; -import 'config_viewmodel.dart'; - -class ConfigPage extends StatefulWidget { - const ConfigPage({Key? key}) : super(key: key); - - @override - ConfigPageState createState() => ConfigPageState(); -} - -class ConfigPageState extends State - with SingleTickerProviderStateMixin, AutomaticKeepAliveClientMixin { - int _initIndex = 0; - BuildContext? childContext; - - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - return BaseStateWidget( - builder: (ref, model, child) { - if (model.list.isEmpty) { - return const EmptyWidget(); - } - - return DefaultTabController( - length: model.list.length, - initialIndex: _initIndex, - child: Builder(builder: (context) { - childContext = context; - return Column( - children: [ - TabBar( - tabs: model.list - .map((e) => Tab( - text: e.title, - )) - .toList(), - isScrollable: true, - indicator: AbsUnderlineTabIndicator( - wantWidth: 20, - borderSide: BorderSide( - color: Theme.of(context).primaryColor, - width: 2, - ), - ), - ), - Expanded( - child: TabBarView( - children: model.list - .map( - (e) => CodeWidget( - content: model.content[e.title] ?? "", - ), - ) - .toList(), - ), - ), - ], - ); - }), - ); - }, - model: configProvider, - onReady: (viewModel) { - viewModel.loadData(); - }, - ); - } - - void editMe(WidgetRef ref) { - if (childContext == null) return; - navigatorState.currentState?.pushNamed(Routes.routeConfigEdit, arguments: { - "title": ref - .read(configProvider) - .list[DefaultTabController.of(childContext!)?.index ?? 0] - .title, - "content": ref.read(configProvider).content[ref - .read(configProvider) - .list[DefaultTabController.of(childContext!)?.index ?? 0] - .title] - }).then((value) async { - if (value != null && (value as String).isNotEmpty) { - await ref.read(configProvider).loadContent(value); - setState(() {}); - } - }); - } - - @override - bool get wantKeepAlive => true; -} - -class CodeWidget extends ConsumerStatefulWidget { - final String content; - - const CodeWidget({ - Key? key, - required this.content, - }) : super(key: key); - - @override - ConsumerState createState() => _CodeWidgetState(); -} - -class _CodeWidgetState extends ConsumerState - with AutomaticKeepAliveClientMixin { - CodeController? _codeController; - - @override - void dispose() { - _codeController?.dispose(); - super.dispose(); - } - - String result = ""; - - @override - void initState() { - result = widget.content; - super.initState(); - } - - @override - Widget build(BuildContext context) { - super.build(context); - _codeController ??= CodeController( - text: result, - language: powershell, - onChange: (value) { - result = value; - }, - theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), - stringMap: { - "export": const TextStyle( - fontWeight: FontWeight.normal, color: Color(0xff6B2375)), - }, - ); - return SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, - ), - child: CodeField( - controller: _codeController!, - expands: true, - readOnly: true, - background: Colors.white, - wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true, - hideColumn: !SpUtil.getBool(spShowLine, defValue: false), - lineNumberStyle: LineNumberStyle( - textStyle: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ), - ); - } - - @override - bool get wantKeepAlive => true; -} diff --git a/lib/module/config/config_viewmodel.dart b/lib/module/config/config_viewmodel.dart deleted file mode 100644 index 37f263d..0000000 --- a/lib/module/config/config_viewmodel.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/base_viewmodel.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/module/config/config_bean.dart'; - -var configProvider = ChangeNotifierProvider((ref) => ConfigViewModel()); - -class ConfigViewModel extends BaseViewModel { - List list = []; - - Map content = {}; - - Future loadData([isLoading = true]) async { - if (isLoading && list.isEmpty) { - loading(notify: true); - } - - HttpResponse> result = await Api.files(); - - if (result.success && result.bean != null) { - list.clear(); - list.addAll(result.bean!); - - for (var element in list) { - await loadContent(element.value!); - } - - success(); - } else { - list.clear(); - failed(result.message, notify: true); - } - } - - Future loadContent(String name) async { - HttpResponse result = await Api.content(name); - - if (result.success && result.bean != null) { - content[name] = result.bean!; - } - } -} diff --git a/lib/module/env/add_env_page.dart b/lib/module/env/add_env_page.dart deleted file mode 100644 index cedebfc..0000000 --- a/lib/module/env/add_env_page.dart +++ /dev/null @@ -1,204 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/module/env/env_viewmodel.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -class AddEnvPage extends ConsumerStatefulWidget { - final EnvBean? envBean; - - const AddEnvPage({Key? key, this.envBean}) : super(key: key); - - @override - ConsumerState createState() => _AddEnvPageState(); -} - -class _AddEnvPageState extends ConsumerState { - late EnvBean envBean; - - final TextEditingController _nameController = TextEditingController(); - final TextEditingController _valueController = TextEditingController(); - final TextEditingController _remarkController = TextEditingController(); - FocusNode focusNode = FocusNode(); - - @override - void initState() { - super.initState(); - if (widget.envBean != null) { - envBean = widget.envBean!; - _nameController.text = envBean.name ?? ""; - _valueController.text = envBean.value ?? ""; - _remarkController.text = envBean.remarks ?? ""; - } else { - envBean = EnvBean(); - } - WidgetsBinding.instance.addPostFrameCallback( - (timeStamp) { - focusNode.requestFocus(); - }, - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: envBean.name == null ? "新增环境变量" : "编辑环境变量", - actions: [ - InkWell( - onTap: () { - submit(); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "名称:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - focusNode: focusNode, - controller: _nameController, - decoration: const InputDecoration( - hintText: "请输入名称", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "值:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _valueController, - maxLines: 8, - minLines: 1, - decoration: const InputDecoration( - hintText: "请输入值", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "备注:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _remarkController, - decoration: const InputDecoration( - hintText: "请输入备注", - ), - autofocus: false, - ), - ], - ), - ), - ], - ), - ), - ); - } - - void submit() async { - if (_nameController.text.isEmpty) { - "名称不能为空".toast(); - return; - } - if (_valueController.text.isEmpty) { - "值不能为空".toast(); - return; - } - - envBean.name = _nameController.text; - envBean.value = _valueController.text; - envBean.remarks = _remarkController.text; - HttpResponse response = await Api.addEnv( - _nameController.text, - _valueController.text, - _remarkController.text, - id: envBean.id, - nId: envBean.nId, - ); - - if (response.success) { - (envBean.sId == null) ? "新增成功" : "修改成功".toast(); - ref.read(envProvider).updateEnv(envBean); - Navigator.of(context).pop(); - } else { - (response.message ?? "").toast(); - } - } -} diff --git a/lib/module/env/env_bean.dart b/lib/module/env/env_bean.dart deleted file mode 100644 index c5f8a86..0000000 --- a/lib/module/env/env_bean.dart +++ /dev/null @@ -1,55 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -@JsonConversion() -class EnvBean { - String? value; - String? sId; - String? _id; - int? id; - int? created; - int? status; - String? timestamp; - String? name; - String? remarks; - - EnvBean( - {this.value, - this.sId, - this.created, - this.status, - this.timestamp, - this.name, - this.remarks}); - - get nId => _id; - - EnvBean.fromJson(Map json) { - value = json['value']; - id = json['id']; - _id = json['_id']; - sId = json.containsKey('_id') - ? json['_id'].toString() - : (json.containsKey('id') ? json['id'].toString() : ""); - created = int.tryParse(json['created'].toString()); - status = json['status']; - timestamp = json['timestamp']; - name = json['name']; - remarks = json['remarks']; - } - - Map toJson() { - final Map data = new Map(); - data['value'] = this.value; - data['_id'] = this.sId; - data['created'] = this.created; - data['status'] = this.status; - data['timestamp'] = this.timestamp; - data['name'] = this.name; - data['remarks'] = this.remarks; - return data; - } - - static EnvBean jsonConversion(Map json) { - return EnvBean.fromJson(json); - } -} diff --git a/lib/module/env/env_detail_page.dart b/lib/module/env/env_detail_page.dart deleted file mode 100644 index 83a3680..0000000 --- a/lib/module/env/env_detail_page.dart +++ /dev/null @@ -1,350 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/module/env/env_viewmodel.dart'; -import 'package:qinglong_app/utils/utils.dart'; - -class EnvDetailPage extends ConsumerStatefulWidget { - final EnvBean envBean; - - const EnvDetailPage(this.envBean, {Key? key}) : super(key: key); - - @override - _TaskDetailPageState createState() => _TaskDetailPageState(); -} - -class _TaskDetailPageState extends ConsumerState { - List actions = []; - - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - actions.clear(); - actions.addAll( - [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - Navigator.of(context) - .pushNamed(Routes.routeAddEnv, arguments: widget.envBean); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "编辑", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - enableTask(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: Material( - color: Colors.transparent, - child: Text( - widget.envBean.status! == 0 ? "禁用" : "启用", - style: const TextStyle( - color: Colors.red, - fontSize: 16, - ), - ), - ), - ), - ), - ], - ); - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: widget.envBean.name ?? "", - actions: [ - InkWell( - onTap: () { - showCupertinoModalPopup( - context: context, - builder: (context) { - return CupertinoActionSheet( - title: Container( - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "更多操作", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - actions: actions, - cancelButton: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: const Material( - color: Colors.transparent, - child: Text( - "取消", - style: TextStyle( - color: Colors.red, - fontSize: 16, - ), - ), - ), - ), - ), - ); - }); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - Icons.more_horiz, - color: Colors.white, - size: 26, - ), - ), - ), - ) - ], - ), - body: SingleChildScrollView( - child: Column( - children: [ - Container( - margin: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 15, - ), - padding: const EdgeInsets.only( - top: 10, - bottom: 10, - ), - decoration: BoxDecoration( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - borderRadius: BorderRadius.circular(15), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - EnvDetailCell( - title: "ID", - desc: widget.envBean.sId ?? "", - ), - EnvDetailCell( - title: "变量名称", - desc: widget.envBean.name ?? "", - ), - EnvDetailCell( - title: "创建时间", - desc: Utils.formatMessageTime(widget.envBean.created ?? 0), - ), - EnvDetailCell( - title: "更新时间", - desc: Utils.formatGMTTime(widget.envBean.timestamp ?? ""), - ), - EnvDetailCell( - title: "值", - desc: widget.envBean.value ?? "", - ), - EnvDetailCell( - title: "备注", - desc: widget.envBean.remarks ?? "", - ), - EnvDetailCell( - title: "变量状态", - desc: widget.envBean.status == 1 ? "已禁用" : "已启用", - hideDivide: true, - ), - ], - ), - ), - SizedBox( - width: MediaQuery.of(context).size.width - 80, - child: CupertinoButton( - padding: const EdgeInsets.symmetric( - vertical: 5, - ), - color: Colors.red, - child: const Text( - "删 除", - style: TextStyle( - fontSize: 16, - ), - ), - onPressed: () { - delTask(context, ref); - }), - ), - const SizedBox( - height: 15, - ), - ], - ), - ), - ); - } - - void enableTask() async { - await ref - .read(envProvider) - .enableEnv(widget.envBean.sId!, widget.envBean.status!); - setState(() {}); - } - - void delTask(BuildContext context, WidgetRef ref) { - showCupertinoDialog( - context: context, - builder: (context) => CupertinoAlertDialog( - title: const Text("确认删除"), - content: Text("确认删除环境变量 ${widget.envBean.name ?? ""} 吗"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () async { - Navigator.of(context).pop(); - await ref.read(envProvider).delEnv(widget.envBean.sId!); - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - } -} - -class EnvDetailCell extends ConsumerWidget { - final String title; - final String? desc; - final Widget? icon; - final bool hideDivide; - final Function? taped; - - const EnvDetailCell({ - Key? key, - required this.title, - this.desc, - this.icon, - this.hideDivide = false, - this.taped, - }) : super(key: key); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only( - top: 10, - left: 15, - right: 10, - bottom: 10, - ), - child: Row( - children: [ - Text( - title, - style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 16, - ), - ), - const SizedBox( - width: 30, - ), - desc != null - ? Expanded( - child: Align( - alignment: Alignment.centerRight, - child: SelectableText( - desc!, - textAlign: TextAlign.right, - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - onTap: () { - if (taped != null) { - taped!(); - } - }, - style: TextStyle( - color: - ref.watch(themeProvider).themeColor.descColor(), - fontSize: 14, - ), - ), - ), - ) - : Expanded( - child: - Align(alignment: Alignment.centerRight, child: icon!), - ), - ], - ), - ), - hideDivide - ? const SizedBox.shrink() - : const Divider( - indent: 15, - ), - ], - ); - } -} diff --git a/lib/module/env/env_page.dart b/lib/module/env/env_page.dart deleted file mode 100644 index 2303f72..0000000 --- a/lib/module/env/env_page.dart +++ /dev/null @@ -1,483 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:qinglong_app/base/base_state_widget.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/empty_widget.dart'; -import 'package:qinglong_app/base/ui/search_cell.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/module/env/env_viewmodel.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/utils.dart'; - -class EnvPage extends StatefulWidget { - const EnvPage({Key? key}) : super(key: key); - - @override - _EnvPageState createState() => _EnvPageState(); -} - -class _EnvPageState extends State { - final TextEditingController _searchController = TextEditingController(); - String currentState = EnvViewModel.allStr; - - @override - void initState() { - super.initState(); - _searchController.addListener(() { - setState(() {}); - }); - } - - @override - Widget build(BuildContext context) { - return BaseStateWidget( - builder: (ref, model, child) { - List prepareList = []; - List list = []; - if (currentState == EnvViewModel.allStr) { - prepareList = model.list; - } else if (currentState == EnvViewModel.enabledStr) { - prepareList = model.enabledList; - } else { - prepareList = model.disabledList; - } - - for (int i = 0; i < prepareList.length; i++) { - EnvBean value = prepareList[i]; - if (_searchController.text.isEmpty || - (value.name?.contains(_searchController.text) ?? false) || - (value.value?.contains(_searchController.text) ?? false) || - (value.remarks?.contains(_searchController.text) ?? false)) { - list.add( - EnvItemCell( - value, - i, - ref, - key: ValueKey(value.sId), - ), - ); - } - } - - return model.list.isEmpty - ? const EmptyWidget() - : RefreshIndicator( - notificationPredicate: (_) { - return true; - }, - color: Theme.of(context).primaryColor, - onRefresh: () async { - return model.loadData(false); - }, - child: SlidableAutoCloseBehavior( - child: currentState == EnvViewModel.disabledStr - ? ListView( - children: [ - searchCell(context, ref), - ...list, - ], - ) - : ReorderableListView( - keyboardDismissBehavior: - ScrollViewKeyboardDismissBehavior.onDrag, - header: searchCell(context, ref), - onReorder: (int oldIndex, int newIndex) { - if (list.length != model.list.length) { - "请先清空搜索关键词".toast(); - return; - } - - setState( - () { - //交换数据 - if (newIndex > oldIndex) { - newIndex -= 1; - } - final EnvBean item = - model.list.removeAt(oldIndex); - model.list.insert(newIndex, item); - model.update( - item.sId ?? "", newIndex, oldIndex); - }, - ); - }, - children: list, - ), - ), - ); - }, - model: envProvider, - onReady: (viewModel) { - viewModel.loadData(true); - }, - ); - } - - Widget searchCell(BuildContext context, WidgetRef ref) { - return Container( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - padding: const EdgeInsets.only( - left: 15, - ), - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: SearchCell( - controller: _searchController, - ), - ), - ), - Material( - color: Colors.transparent, - child: PopupMenuButton( - onSelected: (String result) { - currentState = result; - setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - PopupMenuItem( - child: Text( - EnvViewModel.allStr, - style: TextStyle( - color: currentState == EnvViewModel.allStr - ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 14, - ), - ), - value: EnvViewModel.allStr, - ), - PopupMenuItem( - child: Text( - EnvViewModel.enabledStr, - style: TextStyle( - color: currentState == EnvViewModel.enabledStr - ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 14, - ), - ), - value: EnvViewModel.enabledStr, - ), - PopupMenuItem( - child: Text( - EnvViewModel.disabledStr, - style: TextStyle( - color: currentState == EnvViewModel.disabledStr - ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 14, - ), - ), - value: EnvViewModel.disabledStr, - ), - ], - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 10, - ), - child: Text( - "筛选", - style: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 14, - ), - ), - ), - ), - ), - ], - ), - ); - } -} - -class EnvItemCell extends StatelessWidget { - final EnvBean bean; - final int index; - final WidgetRef ref; - - const EnvItemCell(this.bean, this.index, this.ref, {Key? key}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return Slidable( - key: ValueKey(bean.sId), - endActionPane: ActionPane( - motion: const StretchMotion(), - extentRatio: 0.5, - children: [ - SlidableAction( - backgroundColor: const Color(0xff5D5E70), - onPressed: (_) { - Navigator.of(context) - .pushNamed(Routes.routeAddEnv, arguments: bean); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.pencil_outline, - ), - SlidableAction( - backgroundColor: const Color(0xffA356D6), - onPressed: (_) { - enableEnv(context); - }, - foregroundColor: Colors.white, - icon: bean.status == 0 - ? Icons.dnd_forwardslash - : Icons.check_circle_outline_sharp, - ), - SlidableAction( - backgroundColor: const Color(0xffEA4D3E), - onPressed: (_) { - delEnv(context, ref); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.delete, - ), - ], - ), - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Material( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - child: InkWell( - onTap: () { - Navigator.of(context) - .pushNamed(Routes.routeEnvDetail, arguments: bean); - }, - child: Container( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 8, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Row( - children: [ - bean.status == 1 - ? const SizedBox( - width: 18, - ) - : Container( - padding: const EdgeInsets.symmetric( - horizontal: 5, - ), - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(3), - border: Border.all( - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - width: 1), - ), - child: Text( - "${getIndexByIndex(context, index)}", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - fontSize: 12, - ), - ), - ), - const SizedBox( - width: 5, - ), - ConstrainedBox( - constraints: BoxConstraints.loose( - Size.fromWidth( - MediaQuery.of(context).size.width / 2, - ), - ), - child: Material( - color: Colors.transparent, - child: Text( - bean.name ?? "", - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - ), - ), - const SizedBox( - width: 5, - ), - ConstrainedBox( - constraints: BoxConstraints.loose( - Size.fromWidth( - MediaQuery.of(context).size.width / 3, - ), - ), - child: Visibility( - visible: bean.remarks != null && - bean.remarks!.isNotEmpty, - child: Material( - color: Colors.transparent, - child: Text( - "(${bean.remarks})", - maxLines: 1, - style: TextStyle( - height: 1, - overflow: TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - fontSize: 12, - ), - ), - ), - ), - ), - const SizedBox( - width: 7, - ), - bean.status == 1 - ? Image.asset( - "assets/images/icon_disabled.png", - fit: BoxFit.cover, - width: 35, - ) - : Image.asset( - "assets/images/icon_enable.png", - fit: BoxFit.cover, - width: 35, - ) - ], - ), - ), - const SizedBox( - width: 15, - ), - Material( - color: Colors.transparent, - child: Text( - Utils.formatGMTTime(bean.timestamp ?? ""), - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - const SizedBox( - height: 15, - ), - Material( - color: Colors.transparent, - child: Text( - bean.value ?? "", - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: - ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - ), - ), - ), - const Divider( - height: 1, - indent: 15, - ), - ], - ), - ), - ); - } - - void enableEnv(BuildContext context) { - ref.read(envProvider).enableEnv(bean.sId!, bean.status!); - } - - void delEnv(BuildContext context, WidgetRef ref) { - showCupertinoDialog( - useRootNavigator: false, - context: context, - builder: (context) => CupertinoAlertDialog( - title: const Text("确认删除"), - content: Text("确认删除环境变量 ${bean.name ?? ""} 吗"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () { - Navigator.of(context).pop(); - ref.read(envProvider).delEnv(bean.sId!); - }, - ), - ], - ), - ); - } - - int getIndexByIndex(BuildContext context, int index) { - var list = ref.watch(envProvider.notifier).list; - int result = 0; - - for (int i = 0; i <= index; i++) { - if (list.length > index && list[i].status == 0) { - result++; - } - } - - return result; - } -} diff --git a/lib/module/env/env_viewmodel.dart b/lib/module/env/env_viewmodel.dart deleted file mode 100644 index 05cfbc9..0000000 --- a/lib/module/env/env_viewmodel.dart +++ /dev/null @@ -1,82 +0,0 @@ -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/base_viewmodel.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -var envProvider = ChangeNotifierProvider((ref) => EnvViewModel()); - -class EnvViewModel extends BaseViewModel { - static const String allStr = "全部"; - static const String disabledStr = "已禁用"; - static const String enabledStr = "已启用"; - List list = []; - List disabledList = []; - List enabledList = []; - - Future loadData([isLoading = true]) async { - if (isLoading && list.isEmpty) { - loading(notify: true); - } - - HttpResponse> result = await Api.envs(""); - - if (result.success && result.bean != null) { - list.clear(); - list.addAll(result.bean!); - disabledList.clear(); - disabledList - .addAll(list.where((element) => element.status == 1).toList()); - enabledList.clear(); - enabledList.addAll(list.where((element) => element.status == 0).toList()); - success(); - } else { - list.clear(); - disabledList.clear(); - enabledList.clear(); - failed(result.message, notify: true); - } - } - - Future delEnv(String id) async { - HttpResponse result = await Api.delEnv(id); - if (result.success) { - "删除成功".toast(); - loadData(false); - } else { - failed(result.message, notify: true); - } - } - - void updateEnv(EnvBean result) { - loadData(false); - } - - Future enableEnv(String sId, int status) async { - if (status == 1) { - HttpResponse response = await Api.enableEnv(sId); - - if (response.success) { - "启用成功".toast(); - loadData(false); - } else { - failToast(response.message, notify: true); - } - } else { - HttpResponse response = await Api.disableEnv(sId); - - if (response.success) { - "禁用成功".toast(); - loadData(false); - } else { - failToast(response.message, notify: true); - } - } - } - - void update(String id, int newIndex, int oldIndex) async { - await Api.moveEnv(id, oldIndex, newIndex); - loadData(false); - } -} diff --git a/lib/module/home/home_page.dart b/lib/module/home/home_page.dart deleted file mode 100644 index 3b825e6..0000000 --- a/lib/module/home/home_page.dart +++ /dev/null @@ -1,270 +0,0 @@ -import 'dart:convert'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/module/config/config_page.dart'; -import 'package:qinglong_app/module/env/env_page.dart'; -import 'package:qinglong_app/module/others/other_page.dart'; -import 'package:qinglong_app/module/task/task_page.dart'; -import 'package:move_to_background/move_to_background.dart'; -import 'dart:math' as math; - -import '../../utils/utils.dart'; - -class HomePage extends ConsumerStatefulWidget { - const HomePage({Key? key}) : super(key: key); - - @override - _HomePageState createState() => _HomePageState(); -} - -class _HomePageState extends ConsumerState - with TickerProviderStateMixin { - int _index = 0; - String _title = ""; - bool isNewYear = false; - - List titles = []; - - GlobalKey configKey = GlobalKey(); - - late final AnimationController _controller = AnimationController( - duration: const Duration(milliseconds: 1000), - vsync: this, - )..repeat(); - - @override - void initState() { - isNewYearDuration(); - - initTitles(); - _title = titles[0].title; - super.initState(); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - getSystemBean(); - }); - } - - @override - void dispose() { - _controller.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - List actions = []; - - if (_index == 0) { - actions.add( - InkWell( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeAddTask, - ); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - CupertinoIcons.add, - size: 24, - color: Colors.white, - ), - ), - ), - ), - ); - } else if (_index == 1) { - actions.add( - InkWell( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeAddEnv, - ); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - CupertinoIcons.add, - size: 24, - color: Colors.white, - ), - ), - ), - ), - ); - } else if (_index == 2) { - actions.add(InkWell( - onTap: () { - configKey.currentState?.editMe(ref); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "编辑", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - )); - } - - return WillPopScope( - onWillPop: () async { - await MoveToBackground.moveTaskToBack(); - return false; - }, - child: Scaffold( - appBar: QlAppBar( - canBack: false, - title: _title, - actions: actions, - ), - body: IndexedStack( - index: _index, - children: [ - const Positioned.fill( - child: TaskPage(), - ), - const Positioned.fill( - child: EnvPage(), - ), - Positioned.fill( - child: ConfigPage( - key: configKey, - ), - ), - const Positioned.fill( - child: OtherPage(), - ), - ], - ), - bottomNavigationBar: BottomNavigationBar( - items: titles - .map( - (e) => BottomNavigationBarItem( - icon: (e.celebrate.isNotEmpty) - ? Image.asset( - e.celebrate, - width: 35, - height: 35, - fit: BoxFit.cover, - ) - : Icon(e.icon), - activeIcon: (e.celebrate.isNotEmpty) - ? AnimatedBuilder( - builder: (context, _) { - return Transform.rotate( - angle: _controller.value * 2.0 * math.pi, - child: Image.asset( - e.celebrate, - width: 35, - height: 35, - fit: BoxFit.cover, - ), - ); - }, - animation: _controller, - ) - : Icon(e.checkedIcon), - label: e.title, - ), - ) - .toList(), - currentIndex: _index, - onTap: (index) { - _index = index; - _title = titles[index].title; - setState(() {}); - }, - elevation: 0, - selectedFontSize: 12, - unselectedFontSize: 12, - type: BottomNavigationBarType.fixed, - showSelectedLabels: !isNewYear, - showUnselectedLabels: !isNewYear, - ), - ), - ); - } - - void initTitles() { - titles.clear(); - titles.add( - IndexBean( - CupertinoIcons.timer, - CupertinoIcons.timer_fill, - "定时任务", - celebrate: !isNewYear ? "" : "assets/images/xin.png", - ), - ); - titles.add( - IndexBean( - CupertinoIcons.hammer, - CupertinoIcons.hammer_fill, - "环境变量", - celebrate: !isNewYear ? "" : "assets/images/chun.png", - ), - ); - titles.add( - IndexBean( - CupertinoIcons.settings, - CupertinoIcons.settings_solid, - "配置文件", - celebrate: !isNewYear ? "" : "assets/images/kuai.png", - ), - ); - titles.add( - IndexBean( - CupertinoIcons.cube, - CupertinoIcons.cube_fill, - "其他功能", - celebrate: !isNewYear ? "" : "assets/images/le.png", - ), - ); - } - - void isNewYearDuration() { - DateTime date = DateTime.now(); - DateTime dateYear1 = DateTime(2022, 1, 29); - DateTime dateYear2 = DateTime(2022, 2, 6); - - if (date.isAfter(dateYear1) && date.isBefore(dateYear2)) { - isNewYear = true; - } else { - isNewYear = false; - } - } - - void getSystemBean() async { - var bean = await Api.system(); - if (bean.success) { - Utils.systemBean.version = bean.bean?.version ?? "2.10.13"; - } - } -} - -class IndexBean { - IconData icon; - IconData checkedIcon; - String title; - String celebrate; - - IndexBean(this.icon, this.checkedIcon, this.title, {this.celebrate = ""}); -} diff --git a/lib/module/home/system_bean.dart b/lib/module/home/system_bean.dart deleted file mode 100644 index d160e3f..0000000 --- a/lib/module/home/system_bean.dart +++ /dev/null @@ -1,116 +0,0 @@ -/// @author NewTab - -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -@JsonConversion() -class SystemBean { - String? version; - - SystemBean({this.version}); - - SystemBean.fromJson(Map json) { - version = json['version']; - } - - //2.12.2 以及以上版本,日志从dirs换成了data - bool isUpperVersion2_12_2() { - try { - List? version1 = version?.split("\."); - - String f = version1?[0] ?? "2"; - String s = version1?[1] ?? "10"; - String t = version1?[2] ?? "0"; - - if (f.length == 1) { - f = "0$f"; - } - if (s.length == 1) { - s = "0$s"; - } - if (t.length == 1) { - t = "0$t"; - } - - String tempSum = "$f$s$t"; - - if ((int.tryParse(tempSum) ?? 1) >= 021202) { - return true; - } - - return false; - } catch (e) { - return false; - } - } - - //2.13.0 以及以上版本日志详情接口参数有变化 - bool isUpperVersion2_13_0() { - try { - List? version1 = version?.split("\."); - - String f = version1?[0] ?? "2"; - String s = version1?[1] ?? "10"; - String t = version1?[2] ?? "0"; - - if (f.length == 1) { - f = "0$f"; - } - if (s.length == 1) { - s = "0$s"; - } - if (t.length == 1) { - t = "0$t"; - } - - String tempSum = "$f$s$t"; - - if ((int.tryParse(tempSum) ?? 1) >= 021300) { - return true; - } - - return false; - } catch (e) { - return false; - } - } - - // 2.10.13以上版本,针对任务,环境变量编辑做了修改 - bool isUpperVersion() { - try { - List? version1 = version?.split("\."); - - String f = version1?[0] ?? "2"; - String s = version1?[1] ?? "10"; - String t = version1?[2] ?? "0"; - - if (f.length == 1) { - f = "0$f"; - } - if (s.length == 1) { - s = "0$s"; - } - if (t.length == 1) { - t = "0$t"; - } - - String tempSum = "$f$s$t"; - - if ((int.tryParse(tempSum) ?? 1) > 021013) { - return true; - } - return false; - } catch (e) { - return false; - } - } - - Map toJson() { - final Map data = new Map(); - data['version'] = this.version; - return data; - } - - static SystemBean jsonConversion(Map json) { - return SystemBean.fromJson(json); - } -} diff --git a/lib/module/login/login_bean.dart b/lib/module/login/login_bean.dart deleted file mode 100644 index 1b26726..0000000 --- a/lib/module/login/login_bean.dart +++ /dev/null @@ -1,43 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -@JsonConversion() -class LoginBean { - String? token; - String? lastip; - String? lastaddr; - int? lastlogon; - int? retries; - String? platform; - - LoginBean( - {this.token, - this.lastip, - this.lastaddr, - this.lastlogon, - this.retries, - this.platform}); - - LoginBean.fromJson(Map json) { - token = json['token']; - lastip = json['lastip']; - lastaddr = json['lastaddr']; - lastlogon = int.tryParse(json['lastlogon'].toString()); - retries = json['retries']; - platform = json['platform']; - } - - Map toJson() { - final Map data = new Map(); - data['token'] = this.token; - data['lastip'] = this.lastip; - data['lastaddr'] = this.lastaddr; - data['lastlogon'] = this.lastlogon; - data['retries'] = this.retries; - data['platform'] = this.platform; - return data; - } - - static LoginBean jsonConversion(Map json) { - return LoginBean.fromJson(json); - } -} diff --git a/lib/module/login/login_page.dart b/lib/module/login/login_page.dart deleted file mode 100644 index 5afdb7c..0000000 --- a/lib/module/login/login_page.dart +++ /dev/null @@ -1,737 +0,0 @@ -import 'package:dio_log/dio_log.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_animator/flutter_animator.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/main.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/login_helper.dart'; -import 'package:qinglong_app/utils/utils.dart'; -import 'package:flip_card/flip_card.dart'; - -class LoginPage extends ConsumerStatefulWidget { - final bool doNotLoadLocalData; - - const LoginPage({ - Key? key, - this.doNotLoadLocalData = false, - }) : super(key: key); - - @override - _LoginPageState createState() => _LoginPageState(); -} - -class _LoginPageState extends ConsumerState { - final TextEditingController _hostController = TextEditingController(); - final TextEditingController _userNameController = TextEditingController(); - final TextEditingController _passwordController = TextEditingController(); - final TextEditingController _cIdController = TextEditingController(); - final TextEditingController _cSecretController = TextEditingController(); - GlobalKey cardKey = GlobalKey(); - - bool rememberPassword = false; - - bool useSecretLogin = false; - - @override - void initState() { - super.initState(); - if (!widget.doNotLoadLocalData) { - _hostController.text = getIt().host ?? ""; - useSecretLogin = getIt().useSecretLogined; - if (getIt().userName != null && - getIt().userName!.isNotEmpty) { - if (getIt().useSecretLogined) { - _cIdController.text = getIt().userName!; - } else { - _userNameController.text = getIt().userName!; - } - rememberPassword = true; - } else { - rememberPassword = false; - } - if (getIt().passWord != null && - getIt().passWord!.isNotEmpty) { - if (getIt().useSecretLogined) { - _cSecretController.text = getIt().passWord!; - } else { - _passwordController.text = getIt().passWord!; - } - } - } - getIt().updateToken(""); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - if (useSecretLogin) { - cardKey.currentState?.toggleCard(); - } - }); - } - - GlobalKey loginKey = GlobalKey(); - - @override - Widget build(BuildContext context) { - return Scaffold( - body: AnnotatedRegion( - value: ref.watch(themeProvider).darkMode == true - ? SystemUiOverlayStyle.light - : SystemUiOverlayStyle.dark, - child: ColoredBox( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - child: SingleChildScrollView( - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 40, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox( - height: MediaQuery.of(context).size.height / 8, - ), - Row( - children: [ - Expanded( - child: Align( - alignment: Alignment.centerLeft, - child: Text( - useSecretLogin ? "client_id登录" : "账号登录", - style: TextStyle( - fontSize: 26, - fontWeight: FontWeight.bold, - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - ), - ), - ), - ), - GestureDetector( - onDoubleTap: () { - if (debugBtnIsShow()) { - dismissDebugBtn(); - } else { - showDebugBtn(context, - btnColor: - ref.watch(themeProvider).primaryColor); - } - WidgetsBinding.instance.endOfFrame; - }, - child: Image.asset( - "assets/images/ql.png", - height: 45, - ), - ), - ], - ), - SizedBox( - height: MediaQuery.of(context).size.height / 15, - ), - Row( - children: [ - const SizedBox( - width: 40, - child: Text( - "域名", - style: TextStyle( - fontSize: 16, - ), - ), - ), - const SizedBox( - width: 30, - ), - Expanded( - child: TextField( - onChanged: (_) { - setState(() {}); - }, - controller: _hostController, - decoration: InputDecoration( - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - isDense: true, - contentPadding: const EdgeInsets.all(4), - hintText: "http://1.1.1.1:5700", - hintStyle: TextStyle( - fontSize: 16, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - ), - ), - autofocus: false, - ), - ), - ], - ), - const Divider( - color: Color(0xff999999), - ), - const SizedBox( - height: 10, - ), - FlipCard( - key: cardKey, - flipOnTouch: false, - onFlipDone: (back) { - useSecretLogin = back; - setState(() {}); - }, - direction: FlipDirection.HORIZONTAL, - front: SizedBox( - height: 110, - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - const SizedBox( - child: Text( - "账户", - style: TextStyle( - fontSize: 16, - ), - ), - width: 40, - ), - const SizedBox( - width: 30, - ), - Expanded( - child: TextField( - onChanged: (_) { - setState(() {}); - }, - controller: _userNameController, - decoration: InputDecoration( - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - isDense: true, - contentPadding: const EdgeInsets.all(4), - hintText: "请输入账户", - hintStyle: TextStyle( - fontSize: 16, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - ), - ), - autofocus: false, - ), - ), - ], - ), - const Divider( - color: Color(0xff999999), - ), - const SizedBox( - height: 10, - ), - Row( - children: [ - const SizedBox( - width: 40, - child: Text( - "密码", - style: TextStyle( - fontSize: 16, - ), - ), - ), - const SizedBox( - width: 30, - ), - Expanded( - child: TextField( - onChanged: (_) { - setState(() {}); - }, - controller: _passwordController, - obscureText: true, - decoration: InputDecoration( - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - isDense: true, - contentPadding: const EdgeInsets.all(4), - hintText: "请输入密码", - hintStyle: TextStyle( - fontSize: 16, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - ), - ), - autofocus: false, - ), - ), - ], - ), - const Divider( - color: Color(0xff999999), - ), - ], - ), - ), - back: SizedBox( - height: 110, - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - const SizedBox( - width: 40, - child: Text( - "id", - style: TextStyle( - fontSize: 16, - ), - ), - ), - const SizedBox( - width: 30, - ), - Expanded( - child: TextField( - onChanged: (_) { - setState(() {}); - }, - controller: _cIdController, - decoration: InputDecoration( - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - isDense: true, - contentPadding: const EdgeInsets.all(4), - hintText: "请输入client_id", - hintStyle: TextStyle( - fontSize: 16, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - ), - ), - autofocus: false, - ), - ), - ], - ), - const Divider( - color: Color(0xff999999), - ), - const SizedBox( - height: 10, - ), - Row( - children: [ - const SizedBox( - width: 50, - child: Text( - "secret", - style: TextStyle( - fontSize: 16, - ), - ), - ), - const SizedBox( - width: 20, - ), - Expanded( - child: TextField( - onChanged: (_) { - setState(() {}); - }, - controller: _cSecretController, - obscureText: true, - decoration: InputDecoration( - border: InputBorder.none, - enabledBorder: InputBorder.none, - focusedBorder: InputBorder.none, - isDense: true, - contentPadding: const EdgeInsets.all(4), - hintText: "请输入client_secret", - hintStyle: TextStyle( - fontSize: 16, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - ), - ), - autofocus: false, - ), - ), - ], - ), - const Divider( - color: Color(0xff999999), - ), - ], - ), - ), - ), - const SizedBox( - height: 10, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 25, - ), - child: Row( - children: [ - Checkbox( - value: rememberPassword, - onChanged: (checked) { - rememberPassword = checked ?? false; - setState(() {}); - }, - ), - const Text( - "记住密码", - style: TextStyle( - color: Color(0xff555555), - fontSize: 14, - ), - ), - const Spacer(), - GestureDetector( - onTap: () { - cardKey.currentState?.toggleCard(); - WidgetsBinding.instance - .addPostFrameCallback((timeStamp) { - setState(() {}); - }); - }, - child: Text( - loginByUserName() ? "client_id登录" : "账号登录", - style: const TextStyle( - color: Color(0xff555555), - fontSize: 14, - ), - ), - ), - const SizedBox( - width: 10, - ), - ], - ), - ), - const SizedBox( - height: 30, - ), - Shake( - preferences: const AnimationPreferences( - autoPlay: AnimationPlayStates.None), - key: loginKey, - child: Center( - child: Container( - alignment: Alignment.center, - width: MediaQuery.of(context).size.width * 0.8, - padding: const EdgeInsets.symmetric( - horizontal: 40, - ), - decoration: BoxDecoration( - gradient: LinearGradient( - colors: canClickLoginBtn() - ? [ - const Color(0xff5DD16F), - const Color(0xff089556), - ] - : [ - const Color(0xff5DD16F).withOpacity(0.6), - const Color(0xff089556).withOpacity(0.6), - ], - ), - borderRadius: const BorderRadius.all( - Radius.circular(10), - ), - ), - child: SizedBox( - width: MediaQuery.of(context).size.width - 80, - child: IgnorePointer( - ignoring: !canClickLoginBtn(), - child: Builder( - builder: (context) { - return CupertinoButton( - padding: const EdgeInsets.symmetric( - vertical: 5, - ), - child: isLoading - ? const CupertinoActivityIndicator() - : const Text( - "登 录", - style: TextStyle( - fontSize: 18, - color: Colors.white, - ), - ), - onPressed: () async { - Http.pushedLoginPage = false; - Utils.hideKeyBoard(context); - if (loginByUserName()) { - login(_userNameController.text, - _passwordController.text); - } else { - login(_cIdController.text, - _cSecretController.text); - } - }, - ); - }, - ), - ), - ), - ), - ), - ), - const SizedBox( - height: 30, - ), - (getIt().historyAccounts.isEmpty) - ? const SizedBox.shrink() - : SafeArea( - top: false, - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: Center( - child: Material( - color: Colors.transparent, - child: PopupMenuButton( - onSelected: (UserInfoBean result) { - selected(result); - }, - itemBuilder: (BuildContext context) => - >[ - ...getIt() - .historyAccounts - .map( - (e) => PopupMenuItem( - value: e, - child: buildCell(context, e), - ), - ) - .toList(), - ], - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Image.asset( - "assets/images/icon_history.png", - fit: BoxFit.cover, - width: 16, - ), - const SizedBox( - width: 5, - ), - const Text( - "历史账号", - style: TextStyle( - color: Color(0xff555555), - fontSize: 14, - ), - ), - ], - ), - ), - ), - ), - ), - ), - ], - ), - ), - ), - ), - ); - } - - bool isLoading = false; - - bool loginByUserName() { - return !useSecretLogin; - } - - LoginHelper? helper; - - Future login(String userName, String password) async { - isLoading = true; - setState(() {}); - - helper = LoginHelper(useSecretLogin, _hostController.text, userName, - password, rememberPassword); - var response = await helper!.login(); - dealLoginResponse(response); - } - - void dealLoginResponse(int response) { - isLoading = false; - if (response == LoginHelper.success) { - Navigator.of(context).pushReplacementNamed(Routes.routeHomePage); - } else if (response == LoginHelper.failed) { - loginFailed(); - } else { - twoFact(); - } - } - - void loginFailed() { - isLoading = false; - loginKey.currentState?.forward(); - setState(() {}); - } - - bool canClickLoginBtn() { - if (isLoading) return false; - - if (_hostController.text.isEmpty) return false; - if (!loginByUserName()) { - return _cIdController.text.isNotEmpty && - _cSecretController.text.isNotEmpty; - } else { - return _userNameController.text.isNotEmpty && - _passwordController.text.isNotEmpty; - } - } - - void twoFact() { - String twoFact = ""; - showCupertinoDialog( - context: context, - builder: (_) => CupertinoAlertDialog( - title: const Text("两步验证"), - content: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Material( - color: Colors.transparent, - child: TextField( - onChanged: (value) { - twoFact = value; - }, - maxLines: 1, - keyboardType: TextInputType.number, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入code", - ), - autofocus: true, - ), - ), - ], - ), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () async { - Navigator.of(context).pop(true); - if (helper != null) { - var response = await helper!.loginTwice(twoFact); - dealLoginResponse(response); - } else { - "状态异常,请重新点登录按钮".toast(); - } - }, - ), - ], - )).then((value) { - if (value == null) { - isLoading = false; - setState(() {}); - } - }); - } - - Widget buildCell(BuildContext context, UserInfoBean bean) { - return ListTile( - title: Text( - bean.host ?? "", - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), - subtitle: Padding( - padding: const EdgeInsets.only(top: 10.0), - child: Text( - bean.userName ?? "", - ), - ), - contentPadding: EdgeInsets.zero, - trailing: GestureDetector( - onTap: () { - getIt().removeHistoryAccount(bean.host); - Navigator.pop(context); - - setState(() {}); - }, - child: const Icon( - CupertinoIcons.clear_thick, - size: 20, - ), - ), - ); - } - - void selected(UserInfoBean result) { - _hostController.text = result.host ?? ""; - if (result.useSecretLogined) { - _cIdController.text = result.userName ?? ""; - _cSecretController.text = result.password ?? ""; - if (cardKey.currentState?.isFront ?? false) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - cardKey.currentState?.toggleCard(); - }); - } - } else { - _userNameController.text = result.userName ?? ""; - _passwordController.text = result.password ?? ""; - if (!(cardKey.currentState?.isFront ?? false)) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - cardKey.currentState?.toggleCard(); - }); - } - } - rememberPassword = true; - setState(() {}); - } -} diff --git a/lib/module/login/user_bean.dart b/lib/module/login/user_bean.dart deleted file mode 100644 index e3d2a83..0000000 --- a/lib/module/login/user_bean.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -/// @author NewTab -@JsonConversion() -class UserBean { - String? username; - bool? twoFactorActivated; - - UserBean({this.username, this.twoFactorActivated}); - - UserBean.fromJson(Map json) { - username = json['username']; - twoFactorActivated = json['twoFactorActivated']; - } - - Map toJson() { - final Map data = new Map(); - data['username'] = this.username; - data['twoFactorActivated'] = this.twoFactorActivated; - return data; - } - - static UserBean jsonConversion(Map json) { - return UserBean.fromJson(json); - } -} diff --git a/lib/module/others/about_page.dart b/lib/module/others/about_page.dart deleted file mode 100644 index a6d4a51..0000000 --- a/lib/module/others/about_page.dart +++ /dev/null @@ -1,144 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:package_info_plus/package_info_plus.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:url_launcher/url_launcher.dart'; - -import '../../main.dart'; - -/// @author NewTab - -class AboutPage extends ConsumerStatefulWidget { - const AboutPage({Key? key}) : super(key: key); - - @override - ConsumerState createState() => _AboutPageState(); -} - -class _AboutPageState extends ConsumerState { - String desc = ""; - - @override - void initState() { - super.initState(); - getInfo(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - title: "关于", - ), - body: SizedBox( - width: MediaQuery.of(context).size.width, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - SizedBox( - height: MediaQuery.of(context).size.height / 10, - ), - Image.asset( - "assets/images/ql.png", - height: 50, - ), - const SizedBox( - height: 30, - ), - Text( - "青龙", - style: TextStyle( - fontWeight: FontWeight.w600, - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 20, - ), - ), - const SizedBox( - height: 15, - ), - Text( - "Version ${desc}", - style: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 16, - ), - ), - const SizedBox( - height: 15, - ), - GestureDetector( - onTap: () { - _launchURL("https://t.me/qinglongapp"); - }, - child: Text( - "Telegram频道", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - fontSize: 16, - ), - ), - ), - const Spacer(), - Row( - children: [ - const Spacer(), - GestureDetector( - onTap: () { - _launchURL( - "https://github.com/qinglong-app/qinglong_app/releases"); - }, - child: Text( - "版本更新", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - fontSize: 16, - ), - ), - ), - const SizedBox( - width: 15, - ), - GestureDetector( - onTap: () { - _launchURL("https://github.com/qinglong-app/qinglong_app"); - }, - child: Text( - "项目地址", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - fontSize: 16, - ), - ), - ), - const Spacer(), - ], - ), - const SizedBox( - height: 15, - ), - ], - ), - ), - ); - } - - void _launchURL(String _url) async { - try { - await launch(_url); - } catch (e) { - logger.e(e); - } - } - - void getInfo() async { - PackageInfo packageInfo = await PackageInfo.fromPlatform(); - - String version = packageInfo.version; - - desc = version; - setState(() {}); - } -} diff --git a/lib/module/others/backup/backup_page.dart b/lib/module/others/backup/backup_page.dart deleted file mode 100644 index 151399e..0000000 --- a/lib/module/others/backup/backup_page.dart +++ /dev/null @@ -1,278 +0,0 @@ -import 'dart:convert'; -import 'dart:io'; - -import 'package:file_picker/file_picker.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:path_provider/path_provider.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/json.jc.dart'; -import 'package:qinglong_app/module/env/env_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:share_plus/share_plus.dart'; - -import '../../../base/theme.dart'; -import '../../../base/userinfo_viewmodel.dart'; -import '../../../main.dart'; - -class BackUpPage extends ConsumerStatefulWidget { - const BackUpPage({Key? key}) : super(key: key); - - @override - _BackUpPageState createState() => _BackUpPageState(); -} - -class _BackUpPageState extends ConsumerState { - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - title: '数据备份', - ), - body: Column( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Container( - margin: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 15, - ), - decoration: BoxDecoration( - color: ref.watch(themeProvider).themeColor.settingBordorColor(), - borderRadius: const BorderRadius.all( - Radius.circular(15), - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - getEnv(); - }, - child: Padding( - padding: const EdgeInsets.only( - top: 10, - bottom: 5, - left: 15, - right: 15, - ), - child: Row( - children: [ - Text( - "环境变量备份到本地", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - uploadEnv(context); - }, - child: Padding( - padding: const EdgeInsets.only( - top: 10, - bottom: 5, - left: 15, - right: 15, - ), - child: Row( - children: [ - Text( - "从本地导入环境变量", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - uploadEnvFromFile(); - }, - child: Padding( - padding: const EdgeInsets.only( - top: 10, - bottom: 5, - left: 15, - right: 15, - ), - child: Row( - children: [ - Text( - "从文件导入环境变量", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - shareEnvs(); - }, - child: Padding( - padding: const EdgeInsets.only( - top: 10, - bottom: 5, - left: 15, - right: 15, - ), - child: Row( - children: [ - Text( - "导出环境变量", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - ]), - ) - ], - ), - ); - } - - Future shareEnvs() async { - Directory appDocDir = await getApplicationDocumentsDirectory(); - var dir = Directory("${appDocDir.path}/backup/"); - var fileList = await dir.list().toList(); - List paths = []; - for(var i=0;i().host!); - File file = File("${appDocDir.path}/backup/${uri.host}-${uri.port}.env"); - file = await file.writeAsString(data, flush: true); - "备份成功".toast(); - } - - void uploadEnvFromFile()async{ - var result = await FilePicker.platform.pickFiles(dialogTitle: "请选择env文件"); - if (result == null)return; - File f = File(result.paths[0]!); - var data = await f.readAsString(); - var content = jsonDecode(data) as List; - for (var j = 0; j < content.length; j++) { - var bean = JsonConversion$Json.fromJson(content[j]); - var resp = await Api.addEnv(bean.name!, bean.value!, bean.remarks!); - if (!resp.success){ - resp.message.toast(); - } - } - "备份完成".toast(); - } - } - - void uploadEnv(BuildContext context) async { - Directory appDocDir = await getApplicationDocumentsDirectory(); - List widgets = []; - var dir = Directory("${appDocDir.path}/backup/"); - var fileList = await dir.list().toList(); - for (var i = 0; i < fileList.length; i++) { - var paths = fileList[i].path.split("/"); - widgets.add( - ListTile( - title: Text(paths[paths.length - 1]), - onTap: () async { - File f = File(fileList[i].path); - var data = await f.readAsString(); - var content = jsonDecode(data) as List; - for (var j = 0; j < content.length; j++) { - var bean = JsonConversion$Json.fromJson(content[j]); - var resp = await Api.addEnv(bean.name!, bean.value!, bean.remarks!); - if (!resp.success){ - resp.message.toast(); - } - } - "备份完成".toast(); - - - }, - )); - } - var dialog = SimpleDialog(title: const Text("请选择备份文件"), children: widgets); - await showDialog( - context: context, - builder: (BuildContext context) { - return dialog; - }); - } - diff --git a/lib/module/others/dependencies/add_dependency_page.dart b/lib/module/others/dependencies/add_dependency_page.dart deleted file mode 100644 index 82fc7e0..0000000 --- a/lib/module/others/dependencies/add_dependency_page.dart +++ /dev/null @@ -1,177 +0,0 @@ -import 'package:dio_log/dio_log.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/module/others/dependencies/dependency_viewmodel.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -class AddDependencyPage extends ConsumerStatefulWidget { - const AddDependencyPage({ - Key? key, - }) : super(key: key); - - @override - ConsumerState createState() => _AddDependencyPageState(); -} - -class _AddDependencyPageState extends ConsumerState { - final TextEditingController _nameController = TextEditingController(); - - DepedencyEnum depedencyType = DepedencyEnum.NodeJS; - - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: "新增依赖", - actions: [ - InkWell( - onTap: () { - submit(); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 10, - ), - const Text( - "依赖类型:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - const SizedBox( - height: 10, - ), - DropdownButtonFormField( - items: [ - DropdownMenuItem( - value: DepedencyEnum.NodeJS, - child: Text(DepedencyEnum.NodeJS.name), - ), - DropdownMenuItem( - value: DepedencyEnum.Python3, - child: Text(DepedencyEnum.Python3.name), - ), - DropdownMenuItem( - value: DepedencyEnum.Linux, - child: Text(DepedencyEnum.Linux.name), - ), - ], - value: DepedencyEnum.NodeJS, - onChanged: (value) { - depedencyType = value!; - }, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 10, - ), - const Text( - "名称:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - const SizedBox( - height: 10, - ), - TextField( - controller: _nameController, - maxLines: 10, - minLines: 1, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入名称", - ), - autofocus: false, - ), - ], - ), - ), - ], - ), - ); - } - - void submit() async { - if (_nameController.text.isEmpty) { - "依赖名称不能为空".toast(); - return; - } - - List> list = []; - - List names = _nameController.text.split("\n"); - list.addAll(names - .map( - (e) => { - "name": e, - "type": depedencyType.index, - }, - ) - .toList()); - HttpResponse response = await Api.addDependency(list); - - if (response.success) { - "新增成功".toast(); - ref.read(dependencyProvider).loadData( - depedencyType.name.toLowerCase(), - ); - Navigator.of(context).pop(); - } else { - response.message.toast(); - } - } -} diff --git a/lib/module/others/dependencies/dependency_bean.dart b/lib/module/others/dependencies/dependency_bean.dart deleted file mode 100644 index e596c53..0000000 --- a/lib/module/others/dependencies/dependency_bean.dart +++ /dev/null @@ -1,52 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -/// @author NewTab -@JsonConversion() -class DependencyBean { - String? sId; - int? created; - int? status; - int? type; - String? timestamp; - String? name; - List? log; - String? remark; - - DependencyBean( - {this.sId, - this.created, - this.status, - this.type, - this.timestamp, - this.name, - this.log, - this.remark}); - - DependencyBean.fromJson(Map json) { - sId = json['_id']; - created = int.tryParse(json['created'].toString()); - status = json['status']; - type = json['type']; - timestamp = json['timestamp'].toString(); - name = json['name']; - log = json['log'].cast(); - remark = json['remark']; - } - - Map toJson() { - final Map data = new Map(); - data['_id'] = this.sId; - data['created'] = this.created; - data['status'] = this.status; - data['type'] = this.type; - data['timestamp'] = this.timestamp; - data['name'] = this.name; - data['log'] = this.log; - data['remark'] = this.remark; - return data; - } - - static DependencyBean jsonConversion(Map json) { - return DependencyBean.fromJson(json); - } -} diff --git a/lib/module/others/dependencies/dependency_page.dart b/lib/module/others/dependencies/dependency_page.dart deleted file mode 100644 index e2bf41e..0000000 --- a/lib/module/others/dependencies/dependency_page.dart +++ /dev/null @@ -1,380 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/base_state_widget.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/abs_underline_tabindicator.dart'; -import 'package:qinglong_app/base/ui/menu.dart'; -import 'package:qinglong_app/module/others/dependencies/dependency_bean.dart'; -import 'package:qinglong_app/module/others/dependencies/dependency_viewmodel.dart'; -import 'package:qinglong_app/utils/utils.dart'; - -/// @author NewTab -class DependencyPage extends StatefulWidget { - const DependencyPage({Key? key}) : super(key: key); - - @override - _DependcyPageState createState() => _DependcyPageState(); -} - -class _DependcyPageState extends State - with TickerProviderStateMixin { - List types = []; - - TabController? _tabController; - - @override - void initState() { - super.initState(); - - types.add( - DepedencyEnum.NodeJS, - ); - types.add( - DepedencyEnum.Python3, - ); - types.add( - DepedencyEnum.Linux, - ); - _tabController = TabController(length: types.length, vsync: this); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: "依赖管理", - actions: [ - InkWell( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeAddDependency, - ); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - CupertinoIcons.add, - size: 24, - color: Colors.white, - ), - ), - ), - ), - ], - ), - body: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.max, - children: [ - TabBar( - controller: _tabController, - tabs: types - .map( - (e) => Tab( - text: e.name, - ), - ) - .toList(), - isScrollable: true, - indicator: AbsUnderlineTabIndicator( - wantWidth: 20, - borderSide: BorderSide( - color: Theme.of(context).primaryColor, - width: 2, - ), - ), - ), - Expanded( - child: BaseStateWidget( - onReady: (model) { - model.loadData(types[0].name.toLowerCase()); - model.loadData(types[1].name.toLowerCase()); - model.loadData(types[2].name.toLowerCase()); - }, - model: dependencyProvider, - builder: (context, model, child) { - return TabBarView( - controller: _tabController, - children: types.map( - (e) { - List list; - if (e.index == 0) { - list = model.nodeJsList; - } else if (e.index == 1) { - list = model.python3List; - } else { - list = model.linuxList; - } - - return RefreshIndicator( - child: ListView.builder( - itemBuilder: (context, index) { - return DependencyCell(e, list[index]); - }, - itemCount: list.length, - ), - onRefresh: () { - return model.loadData( - types[_tabController!.index].name.toLowerCase(), - false); - }, - ); - }, - ).toList(), - ); - }, - ), - ), - ], - ), - ); - } -} - -class DependencyCell extends ConsumerWidget { - final DepedencyEnum type; - final DependencyBean bean; - - const DependencyCell(this.type, this.bean, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return ColoredBox( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - child: CupertinoContextMenu( - actions: [ - QLCupertinoContextMenuAction( - child: Text( - bean.status! == 0 ? "安装" : "重新安装", - ), - trailingIcon: CupertinoIcons.ant, - onPressed: () { - Navigator.of(context).pop(); - reInstall(ref, bean.sId); - }, - ), - QLCupertinoContextMenuAction( - child: const Text("查看日志"), - onPressed: () { - Navigator.of(context).pop(); - showLog(ref, bean.sId); - }, - trailingIcon: CupertinoIcons.clock, - ), - QLCupertinoContextMenuAction( - child: const Text("删除"), - onPressed: () { - Navigator.of(context).pop(); - del(ref, bean.sId); - }, - isDestructiveAction: true, - trailingIcon: CupertinoIcons.delete, - ), - ], - previewBuilder: (context, anima, child) { - return IntrinsicWidth( - child: Material( - color: Colors.transparent, - child: Text( - bean.name ?? "", - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 18, - ), - ), - ), - ); - }, - child: SizedBox( - width: MediaQuery.of(context).size.width, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 10, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Material( - color: Colors.transparent, - child: Text( - bean.name ?? "", - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 18, - ), - ), - ), - const SizedBox( - width: 5, - ), - bean.status == 1 - ? Icon( - CupertinoIcons.checkmark_circle, - color: ref.watch(themeProvider).primaryColor, - size: 16, - ) - : (bean.status == 2 - ? const Icon( - CupertinoIcons.clear_circled, - color: Colors.red, - size: 16, - ) - : const SizedBox( - width: 12, - height: 12, - child: CircularProgressIndicator( - strokeWidth: 2, - ), - )), - Expanded( - child: Align( - alignment: Alignment.centerRight, - child: Material( - color: Colors.transparent, - child: Text( - (bean.created == null || bean.created == 0) - ? "-" - : Utils.formatMessageTime(bean.created!), - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - fontSize: 12, - ), - ), - ), - ), - ), - ], - ), - ], - ), - ), - const Divider( - height: 1, - indent: 15, - ), - ], - ), - ), - ), - ); - } - - void showLog(WidgetRef ref, String? sId) { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - showCupertinoDialog( - builder: (BuildContext context) { - return CupertinoAlertDialog( - title: Text( - "${bean.name}运行日志", - maxLines: 1, - style: const TextStyle(overflow: TextOverflow.ellipsis), - ), - content: Container( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 10, - ), - child: bean.log == null - ? const Center( - child: Text("暂无日志"), - ) - : CupertinoScrollbar( - child: SelectableText( - bean.log!.join("\n"), - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - ), - ), - ), - actions: [ - CupertinoDialogAction( - child: Text( - "知道了", - style: TextStyle(color: Theme.of(context).primaryColor), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - }, - context: ref as BuildContext); - }); - } - - void reInstall(WidgetRef ref, String? sId) { - ref.read(dependencyProvider).reInstall(type.name.toLowerCase(), sId ?? ""); - } - - void del(WidgetRef ref, String? sId) { - showCupertinoDialog( - context: ref as BuildContext, - builder: (context) => CupertinoAlertDialog( - title: const Text("确认删除"), - content: Text("确认删除依赖 ${bean.name ?? ""} 吗"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () { - Navigator.of(context).pop(); - ref - .read(dependencyProvider) - .del(type.name.toLowerCase(), sId ?? ""); - }, - ), - ], - ), - ); - } -} diff --git a/lib/module/others/dependencies/dependency_viewmodel.dart b/lib/module/others/dependencies/dependency_viewmodel.dart deleted file mode 100644 index aa70dc2..0000000 --- a/lib/module/others/dependencies/dependency_viewmodel.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/base_viewmodel.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/module/others/dependencies/dependency_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -/// @author NewTab - -var dependencyProvider = ChangeNotifierProvider((ref) => DependencyViewModel()); - -class DependencyViewModel extends BaseViewModel { - List nodeJsList = []; - List python3List = []; - List linuxList = []; - - Future loadData(String type, [bool showLoading = true]) async { - if (showLoading && - ((type == "nodejs" && nodeJsList.isEmpty) || - (type == "python3" && python3List.isEmpty) || - (type == "linux" && linuxList.isEmpty))) { - loading(notify: true); - } - - HttpResponse> response = await Api.dependencies(type); - if (response.success) { - if (type == "nodejs") { - nodeJsList.clear(); - nodeJsList.addAll(response.bean!); - } - if (type == "python3") { - python3List.clear(); - python3List.addAll(response.bean!); - } - if (type == "linux") { - linuxList.clear(); - linuxList.addAll(response.bean!); - } - success(); - } else { - response.message?.toast(); - } - } - - void reInstall(String type, String sId) async { - await Api.dependencyReinstall(sId); - loadData(type); - } - - void del(String type, String sId) async { - "删除中...".toast(); - await Api.delDependency(sId); - loadData(type); - } -} - -enum DepedencyEnum { NodeJS, Python3, Linux } diff --git a/lib/module/others/login_log/login_log_bean.dart b/lib/module/others/login_log/login_log_bean.dart deleted file mode 100644 index 5305ee1..0000000 --- a/lib/module/others/login_log/login_log_bean.dart +++ /dev/null @@ -1,36 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -/// @author NewTab -@JsonConversion() -class LoginLogBean { - int? timestamp; - String? address; - String? ip; - String? platform; - int? status; //0代表成功,1代表失败 - - LoginLogBean( - {this.timestamp, this.address, this.ip, this.platform, this.status}); - - LoginLogBean.fromJson(Map json) { - timestamp = int.tryParse(json['timestamp'].toString()); - address = json['address']; - ip = json['ip']; - platform = json['platform']; - status = json['status']; - } - - Map toJson() { - final Map data = new Map(); - data['timestamp'] = this.timestamp; - data['address'] = this.address; - data['ip'] = this.ip; - data['platform'] = this.platform; - data['status'] = this.status; - return data; - } - - static LoginLogBean jsonConversion(Map json) { - return LoginLogBean.fromJson(json); - } -} diff --git a/lib/module/others/login_log/login_log_page.dart b/lib/module/others/login_log/login_log_page.dart deleted file mode 100644 index ab51a05..0000000 --- a/lib/module/others/login_log/login_log_page.dart +++ /dev/null @@ -1,149 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/lazy_load_state.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/utils.dart'; - -import 'login_log_bean.dart'; - -/// @author NewTab -class LoginLogPage extends ConsumerStatefulWidget { - const LoginLogPage({Key? key}) : super(key: key); - - @override - _LoginLogPageState createState() => _LoginLogPageState(); -} - -class _LoginLogPageState extends ConsumerState - with LazyLoadState { - List list = []; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: "登录日志", - ), - body: list.isEmpty - ? const Center( - child: CupertinoActivityIndicator(), - ) - : ListView.separated( - itemBuilder: (context, index) { - LoginLogBean item = list[index]; - - return Row( - children: [ - const SizedBox( - width: 15, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 10, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "${item.address}", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 14, - ), - ), - const SizedBox( - width: 5, - ), - Padding( - padding: const EdgeInsets.only( - top: 2, - ), - child: Image.asset( - item.status == 0 - ? "assets/images/icon_success.png" - : "assets/images/icon_fail.png", - width: 30, - fit: BoxFit.cover, - ), - ), - ], - ), - const SizedBox( - height: 10, - ), - SelectableText( - "${item.ip}", - selectionWidthStyle: BoxWidthStyle.max, - selectionHeightStyle: BoxHeightStyle.max, - style: TextStyle( - color: - ref.watch(themeProvider).themeColor.descColor(), - fontSize: 14, - ), - ), - const SizedBox( - height: 10, - ), - ], - ), - const Spacer(), - Text( - Utils.formatMessageTime(item.timestamp ?? 0), - style: TextStyle( - fontSize: 12, - color: ref.watch(themeProvider).themeColor.descColor(), - ), - ), - const SizedBox( - width: 15, - ), - ], - ); - }, - itemCount: list.length, - separatorBuilder: (BuildContext context, int index) { - return const Divider( - indent: 15, - height: 1, - ); - }, - ), - ); - } - - Future loadData() async { - HttpResponse> response = await Api.loginLog(); - - if (response.success) { - if (response.bean == null || response.bean!.isEmpty) { - "暂无数据".toast(); - } - list.clear(); - list.addAll(response.bean ?? []); - setState(() {}); - } else { - response.message?.toast(); - } - } - - @override - void onLazyLoad() { - loadData(); - } -} diff --git a/lib/module/others/other_page.dart b/lib/module/others/other_page.dart deleted file mode 100644 index 840040e..0000000 --- a/lib/module/others/other_page.dart +++ /dev/null @@ -1,546 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/main.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -class OtherPage extends ConsumerStatefulWidget { - const OtherPage({Key? key}) : super(key: key); - - @override - _OtherPageState createState() => _OtherPageState(); -} - -class _OtherPageState extends ConsumerState { - var toggleValue = false; - - @override - Widget build(BuildContext context) { - return SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics(), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - margin: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 15, - ), - decoration: BoxDecoration( - color: ref.watch(themeProvider).themeColor.settingBordorColor(), - borderRadius: const BorderRadius.all( - Radius.circular(15), - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeScript, - ); - }, - child: Padding( - padding: const EdgeInsets.only( - top: 10, - bottom: 5, - left: 15, - right: 15, - ), - child: Row( - children: [ - Text( - "脚本管理", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeDependency, - ); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 5, - horizontal: 15, - ), - child: Row( - children: [ - Text( - "依赖管理", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeTaskLog, - ); - }, - child: Padding( - padding: const EdgeInsets.only( - top: 5, - bottom: 5, - left: 15, - right: 15, - ), - child: Row( - children: [ - Text( - "任务日志", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - if (getIt().useSecretLogined) { - "使用client_id方式登录无法获取登录日志".toast(); - } else { - Navigator.of(context).pushNamed( - Routes.routeLoginLog, - ); - } - }, - child: Padding( - padding: const EdgeInsets.only( - top: 5, - bottom: 5, - left: 15, - right: 15, - ), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Text( - "登录日志", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - onTap: () { - if (getIt().useSecretLogined) { - "使用client_id方式登录无法修改密码".toast(); - } else { - Navigator.of(context).pushNamed( - Routes.routeUpdatePassword, - ); - } - }, - behavior: HitTestBehavior.opaque, - child: Padding( - padding: const EdgeInsets.only( - top: 5, - bottom: 10, - left: 15, - right: 15, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "修改密码", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routerSubscription, - ); - }, - behavior: HitTestBehavior.opaque, - child: Padding( - padding: const EdgeInsets.only( - top: 5, - bottom: 10, - left: 15, - right: 15, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "订阅管理", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routerBackup, - ); - }, - behavior: HitTestBehavior.opaque, - child: Padding( - padding: const EdgeInsets.only( - top: 5, - bottom: 10, - left: 15, - right: 15, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "数据备份", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - ], - ), - ), - Container( - margin: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 15, - ), - decoration: BoxDecoration( - color: ref.watch(themeProvider).themeColor.settingBordorColor(), - borderRadius: const BorderRadius.all( - Radius.circular(15), - ), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only( - left: 15, - right: 15, - top: 5, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "夜间模式", - style: TextStyle( - color: - ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - CupertinoSwitch( - value: ref.watch(themeProvider).isInDartMode(), - onChanged: (open) { - ref.watch(themeProvider).changeThemeReal(open); - }, - ), - ], - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeTheme, - ); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 5, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "主题设置", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamed(Routes.routeChangeAccount); - }, - child: Padding( - padding: const EdgeInsets.only( - left: 15, - right: 15, - top: 5, - bottom: 5, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "切换账号", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - const Divider( - indent: 15, - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeAbout, - ); - }, - child: Padding( - padding: const EdgeInsets.only( - left: 15, - right: 15, - top: 5, - bottom: 10, - ), - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - "关于", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - const Spacer(), - const Icon( - CupertinoIcons.right_chevron, - size: 16, - ), - ], - ), - ), - ), - ], - ), - ), - const SizedBox( - height: 30, - ), - Center( - child: SizedBox( - width: MediaQuery.of(context).size.width - 40, - child: CupertinoButton( - padding: const EdgeInsets.symmetric( - vertical: 5, - ), - color: ref.watch(themeProvider).themeColor.buttonBgColor(), - child: const Text( - "退出登录", - style: TextStyle( - fontSize: 16, - ), - ), - onPressed: () { - showCupertinoDialog( - context: context, - builder: (context) => CupertinoAlertDialog( - title: const Text("确认退出登录吗?"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () { - getIt().updateToken(""); - Navigator.of(context) - .pushReplacementNamed(Routes.routeLogin); - }, - ), - ], - ), - ); - }), - ), - ), - const SizedBox( - height: 30, - ), - ], - ), - ); - } -} diff --git a/lib/module/others/scripts/script_add_page.dart b/lib/module/others/scripts/script_add_page.dart deleted file mode 100644 index 269f894..0000000 --- a/lib/module/others/scripts/script_add_page.dart +++ /dev/null @@ -1,186 +0,0 @@ -import 'package:code_text_field/code_text_field.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:highlight/languages/javascript.dart'; -import 'package:highlight/languages/json.dart'; -import 'package:highlight/languages/powershell.dart'; -import 'package:highlight/languages/python.dart'; -import 'package:highlight/languages/vbscript-html.dart'; -import 'package:highlight/languages/yaml.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/sp_const.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -class ScriptAddPage extends ConsumerStatefulWidget { - final String title; - final String path; - - const ScriptAddPage(this.title, this.path, {Key? key}) : super(key: key); - - @override - ConsumerState createState() => _ScriptAddPageState(); -} - -class _ScriptAddPageState extends ConsumerState { - CodeController? _codeController; - late String result; - FocusNode focusNode = FocusNode(); - late String preResult; - - @override - void dispose() { - _codeController?.dispose(); - super.dispose(); - } - - @override - void initState() { - result = "## created by 青龙客户端 ${DateTime.now().toString()}\n\n"; - preResult = result; - super.initState(); - - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - focusNode.requestFocus(); - }); - } - - getLanguageType(String title) { - if (title.endsWith(".js")) { - return javascript; - } - - if (title.endsWith(".sh")) { - return powershell; - } - - if (title.endsWith(".py")) { - return python; - } - if (title.endsWith(".json")) { - return json; - } - if (title.endsWith(".yaml")) { - return yaml; - } - return vbscriptHtml; - } - - @override - Widget build(BuildContext context) { - _codeController ??= CodeController( - text: result, - language: getLanguageType(widget.title), - onChange: (value) { - result = value; - }, - theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), - stringMap: { - "export": const TextStyle(fontWeight: FontWeight.normal, color: Color(0xff6B2375)), - }, - ); - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - FocusManager.instance.primaryFocus?.unfocus(); - - if (preResult == result) { - Navigator.of(context).pop(); - } else { - showCupertinoDialog( - context: context, - useRootNavigator: false, - builder: (childContext) => CupertinoAlertDialog( - title: const Text("温馨提示"), - content: const Text("你新增的内容还没用提交,确定退出吗?"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(childContext).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () { - Navigator.of(childContext).pop(); - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - } - }, - title: '新增${widget.title}', - actions: [ - InkWell( - onTap: () async { - try { - HttpResponse response = await Api.addScript( - widget.title, - widget.path, - result, - ); - if (response.success) { - "提交成功".toast(); - Navigator.of(context).pop(true); - } else { - (response.message ?? "").toast(); - } - } catch (e) {} - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, - ), - child: CodeField( - controller: _codeController!, - expands: true, - wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true, - hideColumn: !SpUtil.getBool(spShowLine, defValue: false), - lineNumberStyle: LineNumberStyle( - textStyle: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/module/others/scripts/script_bean.dart b/lib/module/others/scripts/script_bean.dart deleted file mode 100644 index 3e65f64..0000000 --- a/lib/module/others/scripts/script_bean.dart +++ /dev/null @@ -1,61 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -/// @author NewTab -@JsonConversion() -class ScriptBean { - String? title; - String? value; - bool? disabled; - List? children; - - ScriptBean({this.title, this.value, this.disabled, this.children}); - - ScriptBean.fromJson(Map json) { - title = json['title']; - value = json['value']; - disabled = json['disabled']; - if (json['children'] != null) { - children = []; - json['children'].forEach((v) { - children!.add(new ScriptChildren.fromJson(v)); - }); - } - } - - Map toJson() { - final Map data = new Map(); - data['title'] = this.title; - data['value'] = this.value; - data['disabled'] = this.disabled; - if (this.children != null) { - data['children'] = this.children!.map((v) => v.toJson()).toList(); - } - return data; - } - - static ScriptBean jsonConversion(Map json) { - return ScriptBean.fromJson(json); - } -} - -class ScriptChildren { - String? title; - String? value; - String? parent; - - ScriptChildren({this.title, this.value, this.parent}); - - ScriptChildren.fromJson(Map json) { - title = json['title']; - value = json['value']; - parent = json['parent']; - } - - Map toJson() { - final Map data = new Map(); - data['title'] = this.title; - data['value'] = this.value; - data['parent'] = this.parent; - return data; - } -} diff --git a/lib/module/others/scripts/script_code_detail_page.dart b/lib/module/others/scripts/script_code_detail_page.dart deleted file mode 100644 index 9dd77c8..0000000 --- a/lib/module/others/scripts/script_code_detail_page.dart +++ /dev/null @@ -1,154 +0,0 @@ -import 'package:code_text_field/code_text_field.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:highlight/languages/javascript.dart'; -import 'package:highlight/languages/json.dart'; -import 'package:highlight/languages/powershell.dart'; -import 'package:highlight/languages/python.dart'; -import 'package:highlight/languages/vbscript-html.dart'; -import 'package:highlight/languages/yaml.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/sp_const.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -/// @author NewTab -class ScriptCodeDetailPage extends ConsumerStatefulWidget { - final String title; - final String content; - - const ScriptCodeDetailPage({ - Key? key, - required this.title, - required this.content, - }) : super(key: key); - - @override - ScriptCodeDetailPageState createState() => ScriptCodeDetailPageState(); -} - -class ScriptCodeDetailPageState extends ConsumerState { - CodeController? _codeController; - GlobalKey codeFieldKey = GlobalKey(); - - bool buttonshow = false; - - void scrollToTop() { - codeFieldKey.currentState?.getCodeScroll()?.animateTo(0, - duration: const Duration(milliseconds: 200), curve: Curves.linear); - } - - void floatingButtonVisibility() { - double y = codeFieldKey.currentState?.getCodeScroll()?.offset ?? 0; - if (y > MediaQuery.of(context).size.height / 2) { - if (buttonshow == true) return; - setState(() { - buttonshow = true; - }); - } else { - if (buttonshow == false) return; - setState(() { - buttonshow = false; - }); - } - } - - String suffix = "\n\n\n"; - - @override - void dispose() { - _codeController?.dispose(); - _codeController = null; - super.dispose(); - } - - getLanguageType(String title) { - if (title.endsWith(".js")) { - return javascript; - } - - if (title.endsWith(".sh")) { - return powershell; - } - - if (title.endsWith(".py")) { - return python; - } - if (title.endsWith(".json")) { - return json; - } - if (title.endsWith(".yaml")) { - return yaml; - } - return vbscriptHtml; - } - - late String content; - - @override - void initState() { - content = widget.content; - super.initState(); - } - - @override - Widget build(BuildContext context) { - _codeController ??= CodeController( - text: (content) + suffix, - language: getLanguageType(widget.title), - onChange: (value) { - content = value + suffix; - }, - theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), - stringMap: { - "export": const TextStyle( - fontWeight: FontWeight.normal, color: Color(0xff6B2375)), - }, - ); - return Scaffold( - floatingActionButton: Visibility( - visible: buttonshow, - child: FloatingActionButton( - mini: true, - onPressed: () { - scrollToTop(); - }, - elevation: 2, - backgroundColor: Colors.white, - child: const Icon(CupertinoIcons.up_arrow), - ), - ), - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: widget.title, - ), - body: SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, - ), - child: CodeField( - key: codeFieldKey, - controller: _codeController!, - expands: true, - readOnly: true, - wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true, - hideColumn: !SpUtil.getBool(spShowLine, defValue: false), - lineNumberStyle: LineNumberStyle( - textStyle: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - background: Colors.white, - ), - ), - ), - ); - } -} diff --git a/lib/module/others/scripts/script_detail_page.dart b/lib/module/others/scripts/script_detail_page.dart deleted file mode 100644 index bbe2cfb..0000000 --- a/lib/module/others/scripts/script_detail_page.dart +++ /dev/null @@ -1,362 +0,0 @@ -import 'package:code_text_field/code_text_field.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:highlight/languages/javascript.dart'; -import 'package:highlight/languages/json.dart'; -import 'package:highlight/languages/powershell.dart'; -import 'package:highlight/languages/python.dart'; -import 'package:highlight/languages/vbscript-html.dart'; -import 'package:highlight/languages/yaml.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/sp_const.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/lazy_load_state.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -/// @author NewTab -class ScriptDetailPage extends ConsumerStatefulWidget { - final String title; - final String? path; - - const ScriptDetailPage({ - Key? key, - required this.title, - this.path, - }) : super(key: key); - - @override - _ScriptDetailPageState createState() => _ScriptDetailPageState(); -} - -class _ScriptDetailPageState extends ConsumerState - with LazyLoadState { - String? content; - CodeController? _codeController; - GlobalKey codeFieldKey = GlobalKey(); - - List actions = []; - bool buttonshow = false; - - void scrollToTop() { - codeFieldKey.currentState?.getCodeScroll()?.animateTo(0, - duration: const Duration(milliseconds: 200), curve: Curves.linear); - } - - void floatingButtonVisibility() { - double y = codeFieldKey.currentState?.getCodeScroll()?.offset ?? 0; - if (y > MediaQuery.of(context).size.height / 2) { - if (buttonshow == true) return; - setState(() { - buttonshow = true; - }); - } else { - if (buttonshow == false) return; - setState(() { - buttonshow = false; - }); - } - } - - String suffix = "\n\n\n"; - - @override - void dispose() { - _codeController?.dispose(); - _codeController = null; - super.dispose(); - } - - getLanguageType(String title) { - if (title.endsWith(".js")) { - return javascript; - } - - if (title.endsWith(".sh")) { - return powershell; - } - - if (title.endsWith(".py")) { - return python; - } - if (title.endsWith(".json")) { - return json; - } - if (title.endsWith(".yaml")) { - return yaml; - } - return vbscriptHtml; - } - - @override - void initState() { - super.initState(); - actions.addAll( - [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - if (content == null || content!.isEmpty) { - "未获取到脚本内容,请稍候重试".toast(); - return; - } - Navigator.of(context).pushNamed( - Routes.routeScriptUpdate, - arguments: { - "title": widget.title, - "path": widget.path, - "content": content, - }, - ).then((value) { - if (value != null && value == true) { - Navigator.of(context).pop(true); - } - }); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "编辑", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () async { - Navigator.of(context).pop(); - - showCupertinoDialog( - useRootNavigator: false, - context: context, - builder: (context) => CupertinoAlertDialog( - title: const Text("确认删除"), - content: const Text("确认删除该脚本吗"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () async { - Navigator.of(context).pop(); - HttpResponse result = - await Api.delScript(widget.title, widget.path ?? ""); - if (result.success) { - "删除成功".toast(); - Navigator.of(context).pop(true); - } else { - result.message?.toast(); - } - }, - ), - ], - ), - ); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "删除", - style: TextStyle( - color: Colors.red, - fontSize: 16, - ), - ), - ), - ), - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - if (content != null) { - _codeController ??= CodeController( - text: (content ?? "") + suffix, - language: getLanguageType(widget.title), - onChange: (value) { - content = value + suffix; - }, - theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), - stringMap: { - "export": const TextStyle( - fontWeight: FontWeight.normal, color: Color(0xff6B2375)), - }, - ); - } - return Scaffold( - floatingActionButton: Visibility( - visible: buttonshow, - child: FloatingActionButton( - mini: true, - onPressed: () { - scrollToTop(); - }, - elevation: 2, - backgroundColor: Colors.white, - child: const Icon(CupertinoIcons.up_arrow), - ), - ), - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: widget.title, - actions: [ - InkWell( - onTap: () { - showCupertinoModalPopup( - context: context, - useRootNavigator: false, - builder: (context) { - return CupertinoActionSheet( - title: Container( - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "更多操作", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - actions: actions, - cancelButton: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: const Material( - color: Colors.transparent, - child: Text( - "取消", - style: TextStyle( - color: Colors.red, - fontSize: 16, - ), - ), - ), - ), - ), - ); - }, - ); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - Icons.more_horiz, - color: Colors.white, - size: 26, - ), - ), - ), - ), - ], - ), - body: content == null - ? const Center( - child: CupertinoActivityIndicator(), - ) - : SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: - SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, - ), - child: CodeField( - key: codeFieldKey, - controller: _codeController!, - expands: true, - readOnly: true, - wrap: SpUtil.getBool(spShowLine, defValue: false) - ? false - : true, - hideColumn: !SpUtil.getBool(spShowLine, defValue: false), - lineNumberStyle: LineNumberStyle( - textStyle: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - background: Colors.white, - ), - ), - ), - ); - } - - Future loadData() async { - HttpResponse response = await Api.scriptDetail( - widget.title, - widget.path, - ); - - if (response.success) { - content = response.bean; - setState(() {}); - Future.delayed( - const Duration( - seconds: 1, - ), - () { - codeFieldKey.currentState - ?.getCodeScroll() - ?.addListener(floatingButtonVisibility); - }, - ); - } else { - response.message?.toast(); - } - } - - @override - void onLazyLoad() { - loadData(); - } -} diff --git a/lib/module/others/scripts/script_edit_page.dart b/lib/module/others/scripts/script_edit_page.dart deleted file mode 100644 index a5b918f..0000000 --- a/lib/module/others/scripts/script_edit_page.dart +++ /dev/null @@ -1,186 +0,0 @@ -import 'package:code_text_field/code_text_field.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:highlight/languages/javascript.dart'; -import 'package:highlight/languages/json.dart'; -import 'package:highlight/languages/powershell.dart'; -import 'package:highlight/languages/python.dart'; -import 'package:highlight/languages/vbscript-html.dart'; -import 'package:highlight/languages/yaml.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/sp_const.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/utils/extension.dart'; -import 'package:qinglong_app/utils/sp_utils.dart'; - -class ScriptEditPage extends ConsumerStatefulWidget { - final String content; - final String title; - final String path; - - const ScriptEditPage(this.title, this.path, this.content, {Key? key}) - : super(key: key); - - @override - _ScriptEditPageState createState() => _ScriptEditPageState(); -} - -class _ScriptEditPageState extends ConsumerState { - CodeController? _codeController; - late String result; - FocusNode focusNode = FocusNode(); - late String preResult; - - @override - void dispose() { - _codeController?.dispose(); - super.dispose(); - } - - @override - void initState() { - result = widget.content; - preResult = widget.content; - super.initState(); - - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - focusNode.requestFocus(); - }); - } - - getLanguageType(String title) { - if (title.endsWith(".js")) { - return javascript; - } - - if (title.endsWith(".sh")) { - return powershell; - } - - if (title.endsWith(".py")) { - return python; - } - if (title.endsWith(".json")) { - return json; - } - if (title.endsWith(".yaml")) { - return yaml; - } - return vbscriptHtml; - } - - @override - Widget build(BuildContext context) { - _codeController ??= CodeController( - text: widget.content, - language: getLanguageType(widget.title), - onChange: (value) { - result = value; - }, - theme: ref.watch(themeProvider).themeColor.codeEditorTheme(), - stringMap: { - "export": const TextStyle( - fontWeight: FontWeight.normal, color: Color(0xff6B2375)), - }, - ); - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - FocusManager.instance.primaryFocus?.unfocus(); - - if (preResult == result) { - Navigator.of(context).pop(); - } else { - showCupertinoDialog( - context: context, - useRootNavigator: false, - builder: (childContext) => CupertinoAlertDialog( - title: const Text("温馨提示"), - content: const Text("你编辑的内容还没用提交,确定退出吗?"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(childContext).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () { - Navigator.of(childContext).pop(); - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - } - }, - title: '编辑${widget.title}', - actions: [ - InkWell( - onTap: () async { - HttpResponse response = - await Api.updateScript(widget.title, widget.path, result); - if (response.success) { - "提交成功".toast(); - Navigator.of(context).pop(true); - } else { - (response.message ?? "").toast(); - } - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SafeArea( - top: false, - child: Padding( - padding: EdgeInsets.symmetric( - horizontal: SpUtil.getBool(spShowLine, defValue: false) ? 0 : 10, - ), - child: CodeField( - controller: _codeController!, - expands: true, - background: Colors.white, - wrap: SpUtil.getBool(spShowLine, defValue: false) ? false : true, - hideColumn: !SpUtil.getBool(spShowLine, defValue: false), - lineNumberStyle: LineNumberStyle( - textStyle: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ), - ), - ); - } -} diff --git a/lib/module/others/scripts/script_page.dart b/lib/module/others/scripts/script_page.dart deleted file mode 100644 index f435901..0000000 --- a/lib/module/others/scripts/script_page.dart +++ /dev/null @@ -1,252 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/lazy_load_state.dart'; -import 'package:qinglong_app/base/ui/search_cell.dart'; -import 'package:qinglong_app/module/others/scripts/script_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -import 'script_upload_page.dart'; - -/// @author NewTab -class ScriptPage extends ConsumerStatefulWidget { - const ScriptPage({Key? key}) : super(key: key); - - @override - _ScriptPageState createState() => _ScriptPageState(); -} - -class _ScriptPageState extends ConsumerState - with LazyLoadState { - List list = []; - final TextEditingController _searchController = TextEditingController(); - - final TextEditingController _nameController = TextEditingController(); - String? path; - - @override - void initState() { - super.initState(); - _searchController.addListener(() { - setState(() {}); - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: "脚本管理", - actions: [ - InkWell( - onTap: () { - addScript(); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - CupertinoIcons.add, - size: 24, - color: Colors.white, - ), - ), - ), - ), - ], - ), - body: list.isEmpty - ? const Center( - child: CupertinoActivityIndicator(), - ) - : RefreshIndicator( - color: Theme.of(context).primaryColor, - onRefresh: () async { - await loadData(); - return Future.value(); - }, - child: ListView.builder( - physics: const AlwaysScrollableScrollPhysics(), - keyboardDismissBehavior: - ScrollViewKeyboardDismissBehavior.onDrag, - itemBuilder: (context, index) { - if (index == 0) { - return searchCell(ref); - } - - ScriptBean item = list[index - 1]; - - if (_searchController.text.isEmpty || - (item.title?.contains(_searchController.text) ?? false) || - (item.value?.contains(_searchController.text) ?? false) || - ((item.children?.where((e) { - return (e.title?.contains(_searchController.text) ?? - false) || - (e.value?.contains(_searchController.text) ?? - false); - }).isNotEmpty ?? - false))) { - return ColoredBox( - color: - ref.watch(themeProvider).themeColor.settingBgColor(), - child: - (item.children != null && item.children!.isNotEmpty) - ? ExpansionTile( - title: Text( - item.title ?? "", - style: TextStyle( - color: (item.disabled ?? false) - ? ref - .watch(themeProvider) - .themeColor - .descColor() - : ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - children: item.children! - .where((element) { - if (_searchController.text.isEmpty) { - return true; - } - return (element.title?.contains( - _searchController.text) ?? - false) || - (element.value?.contains( - _searchController.text) ?? - false); - }) - .map((e) => ListTile( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeScriptDetail, - arguments: { - "title": e.title, - "path": e.parent, - }, - ).then((value) { - if (value != null && - value == true) { - loadData(); - } - }); - }, - title: Text( - e.title ?? "", - style: TextStyle( - color: (item.disabled ?? false) - ? ref - .watch(themeProvider) - .themeColor - .descColor() - : ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 14, - ), - ), - )) - .toList(), - ) - : ListTile( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeScriptDetail, - arguments: { - "title": item.title, - "path": "", - }, - ).then( - (value) { - if (value != null && value == true) { - loadData(); - } - }, - ); - }, - title: Text( - item.title ?? "", - style: TextStyle( - color: (item.disabled ?? false) - ? ref - .watch(themeProvider) - .themeColor - .descColor() - : ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - ), - ); - } else { - return const SizedBox.shrink(); - } - }, - itemCount: list.length + 1, - ), - ), - ); - } - - Widget searchCell(WidgetRef context) { - return Container( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 10, - ), - child: SearchCell( - controller: _searchController, - ), - ); - } - - Future loadData() async { - HttpResponse> response = await Api.scripts(); - - if (response.success) { - if (response.bean == null || response.bean!.isEmpty) { - "暂无数据".toast(); - } - list.clear(); - list.addAll(response.bean ?? []); - setState(() {}); - } else { - response.message?.toast(); - } - } - - @override - void onLazyLoad() { - loadData(); - } - - String scriptPath = ""; - - void addScript() { - List paths = list - .where((element) => element.children?.isNotEmpty ?? false) - .map((e) => e.title) - .toList(); - - Navigator.of(context).push(MaterialPageRoute( - builder: (context) => ScriptUploadPage(paths: paths))); - } -} diff --git a/lib/module/others/scripts/script_upload_page.dart b/lib/module/others/scripts/script_upload_page.dart deleted file mode 100644 index 10c1896..0000000 --- a/lib/module/others/scripts/script_upload_page.dart +++ /dev/null @@ -1,425 +0,0 @@ -import 'dart:io'; -import 'dart:math'; - -import 'package:file_picker/file_picker.dart'; -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:path/path.dart'; -import 'package:qinglong_app/module/others/scripts/script_code_detail_page.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -/// @author NewTab - -class ScriptUploadPage extends ConsumerStatefulWidget { - final List paths; - - const ScriptUploadPage({ - Key? key, - required this.paths, - }) : super(key: key); - - @override - ConsumerState createState() => ScriptUploadPageState(); -} - -class ScriptUploadPageState extends ConsumerState { - List list = []; - - final TextEditingController _nameController = TextEditingController(); - String scriptPath = ""; - File? file; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - title: "新增脚本", - actions: [ - InkWell( - onTap: () { - submit(context); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 30, - ), - const TitleWidget( - "脚本名称", - ), - TextField( - controller: _nameController, - decoration: InputDecoration( - contentPadding: const EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入脚本名称", - hintStyle: TextStyle( - fontSize: 14, - color: ref.watch(themeProvider).themeColor.descColor(), - ), - ), - autofocus: false, - ), - const SizedBox( - height: 30, - ), - const TitleWidget( - "脚本目录", - ), - const SizedBox( - height: 10, - ), - DropdownButtonFormField( - items: widget.paths - .map((e) => DropdownMenuItem( - value: e, - child: SizedBox( - width: MediaQuery.of(context).size.width / 2, - child: Text( - e ?? "", - maxLines: 2, - ), - ), - )) - .toList() - ..insert( - 0, - DropdownMenuItem( - value: "", - child: SizedBox( - width: MediaQuery.of(context).size.width / 2, - child: const Text( - "根目录", - maxLines: 2, - ), - ), - ), - ), - style: TextStyle( - fontSize: 14, - color: ref.watch(themeProvider).themeColor.titleColor(), - ), - decoration: const InputDecoration( - isDense: true, - contentPadding: EdgeInsets.symmetric( - vertical: 15, - ), - enabledBorder: UnderlineInputBorder( - borderSide: BorderSide( - color: Color(0xfff5f5f5), - ), - ), - border: UnderlineInputBorder( - borderSide: BorderSide( - color: Color(0xfff5f5f5), - ), - ), - ), - value: scriptPath, - onChanged: (value) { - scriptPath = value ?? ""; - }, - ), - const SizedBox( - height: 30, - ), - const TitleWidget( - "上传脚本", - ), - const SizedBox( - height: 10, - ), - Container( - height: 80, - alignment: Alignment.centerLeft, - child: file == null ? addWidget() : addedWidget(context), - ), - ], - ), - ), - const SizedBox( - height: 50, - ), - ], - ), - ), - ); - } - - Widget addWidget() { - return GestureDetector( - onTap: () async { - FilePickerResult? result = await FilePicker.platform.pickFiles(); - if (result != null && - result.files.isNotEmpty && - result.files.single.path != null) { - file = File(result.files.single.path!); - - if (file == null) return; - if (file!.lengthSync() > 5242880) { - file = null; - "最大支持上传5M的文件".toast(); - return; - } - - _nameController.text = getFileName(); - setState(() {}); - } - }, - child: Container( - margin: const EdgeInsets.only( - top: 10, - ), - width: 70, - height: 70, - decoration: BoxDecoration( - color: const Color(0xfff3f5f7), - borderRadius: BorderRadius.circular(5), - ), - child: Center( - child: Image.asset( - "assets/images/icon_add_file.png", - width: 50, - fit: BoxFit.cover, - ), - ), - ), - ); - } - - Widget addedWidget(BuildContext context) { - return GestureDetector( - onTap: () async { - try { - String content = await file!.readAsString(); - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => ScriptCodeDetailPage( - title: getFileName(), - content: content, - ), - ), - ); - } catch (e) { - e.toString().toast(); - } - }, - behavior: HitTestBehavior.opaque, - child: Container( - height: 80, - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: Row( - children: [ - Image.asset( - getIconBySuffix(), - width: 50, - fit: BoxFit.cover, - ), - const SizedBox( - width: 15, - ), - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - getFileName(), - style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 16, - ), - ), - const SizedBox( - height: 5, - ), - Text( - getFileSize(file!.path, 1), - style: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ], - ), - ), - const Spacer(), - GestureDetector( - onTap: () { - file = null; - _nameController.text = ""; - setState(() {}); - }, - child: Icon( - CupertinoIcons.clear, - size: 20, - color: ref.watch(themeProvider).themeColor.descColor(), - ), - ), - ], - ), - ), - ); - } - - String getFileSize(String filepath, int decimals) { - var file = File(filepath); - int bytes = file.lengthSync(); - if (bytes <= 0) return "0 B"; - const suffixes = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]; - var i = (log(bytes) / log(1024)).floor(); - return '${(bytes / pow(1024, i)).toStringAsFixed(decimals)} ${suffixes[i]}'; - } - - String getFileName() { - return basename(file!.path); - } - - String getIconBySuffix() { - String end = file!.path; - - if (end.endsWith(".py")) { - return "assets/images/py.png"; - } - if (end.endsWith(".js")) { - return "assets/images/js.png"; - } - if (end.endsWith(".ts")) { - return "assets/images/ts.png"; - } - if (end.endsWith(".json")) { - return "assets/images/json.png"; - } - if (end.endsWith(".sh")) { - return "assets/images/shell.png"; - } - return "assets/images/other.png"; - } - - void submit(BuildContext context) async { - try { - if (_nameController.text.isEmpty) { - "请输入文件名称".toast(); - return; - } - - if (file == null) { - Navigator.of(context).pushNamed( - Routes.routeScriptAdd, - arguments: { - "title": _nameController.text, - "path": scriptPath, - }, - ).then((value) { - if (value != null && value == true) { - Navigator.of(context).pop(true); - } - }); - } else { - String content = await file!.readAsString(); - HttpResponse response = await Api.addScript( - _nameController.text, - scriptPath, - content, - ); - if (response.success) { - "提交成功".toast(); - - String command = - "task $scriptPath${(scriptPath.isNotEmpty) ? separator : ""}${getFileName()} "; - - String? cron = getCronString(content, getFileName()); - Navigator.of(context).popAndPushNamed( - Routes.routeAddTask, - arguments: TaskBean( - name: _nameController.text, - command: command, - schedule: cron, - ), - ); - } else { - (response.message ?? "").toast(); - } - } - } catch (e) { - e.toString().toast(); - } - } - - static String? getCronString(String pre, String fileName) { - String reg = - "([\\d\\*]*[\\*-\\/,\\d]*[\\d\\*] ){4,5}[\\d\\*]*[\\*-\\/,\\d]*[\\d\\*]( |,|\").*$fileName"; - RegExp regExp = RegExp(reg); - RegExpMatch? result = regExp.firstMatch(pre); - return result?[0]?.replaceAll(fileName, "").trim(); - } -} - -class TitleWidget extends ConsumerWidget { - final String title; - final bool required; - - const TitleWidget( - this.title, { - Key? key, - this.required = false, - }) : super(key: key); - - @override - Widget build(BuildContext context, ref) { - return RichText( - text: TextSpan( - text: !required ? "" : "* ", - style: const TextStyle( - color: Color(0xFFF02D2D), - ), - children: [ - TextSpan( - text: title, - style: TextStyle( - fontSize: 16, - color: ref.watch(themeProvider).themeColor.titleColor(), - ), - ), - ], - ), - ); - } -} diff --git a/lib/module/others/subscription/subscription_add_page.dart b/lib/module/others/subscription/subscription_add_page.dart deleted file mode 100644 index 8a2ad13..0000000 --- a/lib/module/others/subscription/subscription_add_page.dart +++ /dev/null @@ -1,596 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -class SubscriptionAddPage extends StatefulWidget { - final Subscription? bean; - - const SubscriptionAddPage(this.bean, {Key? key}) : super(key: key); - - @override - State createState() => _SubscriptionAddPageState(); -} - -class _SubscriptionAddPageState extends State { - late Subscription _bean; - - late String? _scheduleType; - late String? _type; - - late String? _intervalScheduleType; - late String? _intervalScheduleValue; - - - @override - void initState() { - super.initState(); - if (widget.bean == null) { - _bean = Subscription(); - _bean.scheduleType = ""; - _type = "public-repo"; - _scheduleType = "crontab"; - - _intervalScheduleType = "days"; - } else { - _bean = widget.bean!; - _type = widget.bean?.type; - _scheduleType = widget.bean?.scheduleType; - } - } - - final TextEditingController _nameController = TextEditingController(); - final TextEditingController _urlController = TextEditingController(); - final TextEditingController _branchController = TextEditingController(); - final TextEditingController _intervalScheduleValueController = TextEditingController(); - final TextEditingController _scheduleController = TextEditingController(); - final TextEditingController _whiteListController = TextEditingController(); - final TextEditingController _blackListController = TextEditingController(); - final TextEditingController _dependenceController = TextEditingController(); - final TextEditingController _extensionsController = TextEditingController(); - final TextEditingController _taskBeforeController = TextEditingController(); - final TextEditingController _taskAfterController = TextEditingController(); - FocusNode focusNode = FocusNode(); - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: _bean.name == null ? "新增订阅" : "编辑订阅", - actions: [ - InkWell( - onTap: () { - submit(context); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "名称:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - focusNode: focusNode, - controller: _nameController, - decoration: const InputDecoration( - hintText: "请输入名称", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "类型:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Row( - children: [ - Radio( - value: "public-repo", - groupValue: _type, - onChanged: (data) { - setState(() { - _type = data as String?; - }); - }), - const Text("公开仓库"), - ], - ), - Row( - children: [ - Radio( - value: "private-repo", - groupValue: _type, - onChanged: (data) { - setState(() { - _type = data as String?; - }); - }), - const Text("私有仓库"), - ], - ), - Row( - children: [ - Radio( - value: "file", - groupValue: _type, - onChanged: (data) { - setState(() { - _type = data as String?; - }); - }), - const Text("单文件"), - ], - ), - ], - ) - ], - ), - ), - const Divider( - height: 10, - thickness: 2, - indent: 15, - endIndent: 15, - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "链接:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _urlController, - maxLines: 8, - minLines: 1, - decoration: const InputDecoration( - hintText: "请输入仓库链接", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "分支:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _branchController, - decoration: const InputDecoration( - hintText: "请输入分支", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "定时类型:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Row( - children: [ - Radio( - value: "crontab", - groupValue: _scheduleType, - onChanged: (data) { - setState(() { - _scheduleType = data as String?; - }); - }), - const Text("crontab"), - ], - ), - Row( - children: [ - Radio( - value: "interval", - groupValue: _scheduleType, - onChanged: (data) { - setState(() { - _scheduleType = data as String?; - }); - }), - const Text("interval"), - ], - ), - ], - ) - ], - ), - ), - const Divider( - height: 10, - thickness: 2, - indent: 15, - endIndent: 15, - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "定时规则:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - getScheduler(context) - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "白名单:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _whiteListController, - decoration: const InputDecoration( - hintText: "请输入白名单", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "黑名单:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _blackListController, - decoration: const InputDecoration( - hintText: "请输入黑名单", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "依赖文件:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _dependenceController, - decoration: const InputDecoration( - hintText: "请输入依赖文件", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "文件后缀:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _extensionsController, - decoration: const InputDecoration( - hintText: "请输入文件后缀", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "执行前:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _taskBeforeController, - decoration: const InputDecoration( - hintText: "执行前", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "执行后:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _taskAfterController, - decoration: const InputDecoration( - hintText: "执行后", - ), - autofocus: false, - ), - ], - ), - ), - ], - ), - ), - ); - } - - Widget getScheduler(BuildContext context) { - if (_scheduleType == "crontab") { - return TextField( - controller: _scheduleController, - decoration: const InputDecoration( - hintText: "秒(可选) 分 时 天 月 周", - ), - autofocus: false, - ); - } else { - return Row( - children: [ - const Text("每"), - SizedBox( - width: 350, - child: TextField( - controller: _intervalScheduleValueController, - textAlign: TextAlign.center, - decoration: const InputDecoration( - hintText: "", - ), - autofocus: false, - ), - ), - - DropdownButton( - underline: Container(height: 0), - value: _intervalScheduleType, - items: const [ - DropdownMenuItem(child: Text("时"),value: "hours",), - DropdownMenuItem(child: Text("天"),value: "days",), - DropdownMenuItem(child: Text("周"),value: "weeks",), - ], - onChanged: (data) {setState(() { - _intervalScheduleType = data; - });}) - ], - ); - } - } - - void submit(BuildContext context) async { - if (_nameController.text.isEmpty){ - "名称不能为空".toast(); - return; - }else{ - _bean.name = _nameController.value.text; - } - if (_urlController.text.isEmpty){ - "链接不能为空".toast(); - return; - }else{ - _bean.url = _urlController.value.text; - } - - _bean.type = _type; - _bean.branch = _branchController.value.text; - if (_scheduleType != null && _scheduleType == "crontab"){ - if (_scheduleController.text.isEmpty){ - "定时规则不能为空".toast(); - return; - }else{ - _bean.schedule = _scheduleController.value.text; - } - }else{ - if (_intervalScheduleValueController.text.isEmpty){ - "定时规则不能为空".toast(); - return; - }else{ - var inter = IntervalSchedule(); - inter.type = _intervalScheduleType; - inter.value = int.tryParse(_intervalScheduleValueController.value.text); - _bean.intervalSchedule = inter; - } - } - _bean.alias = _bean.name; - _bean.scheduleType = _scheduleType; - _bean.whitelist = _whiteListController.value.text; - _bean.blacklist = _blackListController.value.text; - _bean.extensions = _extensionsController.value.text; - _bean.dependences = _dependenceController.value.text; - _bean.subBefore = _taskBeforeController.value.text; - _bean.subAfter = _taskAfterController.value.text; - var data = await Api.postSubscription(_bean); - if (!data.success){ - data.message.toast(); - }else{ - "添加成功".toast(); - Navigator.of(context).pop(); - } - } -} diff --git a/lib/module/others/subscription/subscription_bean.dart b/lib/module/others/subscription/subscription_bean.dart deleted file mode 100644 index 8bc422f..0000000 --- a/lib/module/others/subscription/subscription_bean.dart +++ /dev/null @@ -1,310 +0,0 @@ -class Subscription { - int? _id; - String? _name; - String? _url; - dynamic _schedule; - IntervalSchedule? _intervalSchedule; - String? _type; - String? _whitelist; - String? _blacklist; - int? _status; - String? _dependences; - dynamic _extensions; - dynamic _subBefore; - dynamic _subAfter; - String? _branch; - dynamic _pullType; - dynamic _pullOption; - int? _pid; - int? _isDisabled; - String? _logPath; - String? _scheduleType; - String? _alias; - String? _createdAt; - String? _updatedAt; - - Subscription( - {int? id, - String? name, - String? url, - dynamic schedule, - IntervalSchedule? intervalSchedule, - String? type, - String? whitelist, - String? blacklist, - int? status, - String? dependences, - dynamic extensions, - dynamic subBefore, - dynamic subAfter, - String? branch, - dynamic pullType, - dynamic pullOption, - int? pid, - int? isDisabled, - String? logPath, - String? scheduleType, - String? alias, - String? createdAt, - String? updatedAt}) { - if (id != null) { - this._id = id; - } - if (name != null) { - this._name = name; - } - if (url != null) { - this._url = url; - } - if (schedule != null) { - this._schedule = schedule; - } - if (intervalSchedule != null) { - this._intervalSchedule = intervalSchedule; - } - if (type != null) { - this._type = type; - } - if (whitelist != null) { - this._whitelist = whitelist; - } - if (blacklist != null) { - this._blacklist = blacklist; - } - if (status != null) { - this._status = status; - } - if (dependences != null) { - this._dependences = dependences; - } - if (extensions != null) { - this._extensions = extensions; - } - if (subBefore != null) { - this._subBefore = subBefore; - } - if (subAfter != null) { - this._subAfter = subAfter; - } - if (branch != null) { - this._branch = branch; - } - if (pullType != null) { - this._pullType = pullType; - } - if (pullOption != null) { - this._pullOption = pullOption; - } - if (pid != null) { - this._pid = pid; - } - if (isDisabled != null) { - this._isDisabled = isDisabled; - } - if (logPath != null) { - this._logPath = logPath; - } - if (scheduleType != null) { - this._scheduleType = scheduleType; - } - if (alias != null) { - this._alias = alias; - } - if (createdAt != null) { - this._createdAt = createdAt; - } - if (updatedAt != null) { - this._updatedAt = updatedAt; - } - } - - int? get id => _id; - - set id(int? id) => _id = id; - - String? get name => _name; - - set name(String? name) => _name = name; - - String? get url => _url; - - set url(String? url) => _url = url; - - dynamic get schedule => _schedule; - - set schedule(dynamic schedule) => _schedule = schedule; - - IntervalSchedule? get intervalSchedule => _intervalSchedule; - - set intervalSchedule(IntervalSchedule? intervalSchedule) => - _intervalSchedule = intervalSchedule; - - String? get type => _type; - - set type(String? type) => _type = type; - - String? get whitelist => _whitelist; - - set whitelist(String? whitelist) => _whitelist = whitelist; - - String? get blacklist => _blacklist; - - set blacklist(String? blacklist) => _blacklist = blacklist; - - int? get status => _status; - - set status(int? status) => _status = status; - - String? get dependences => _dependences; - - set dependences(String? dependences) => _dependences = dependences; - - dynamic get extensions => _extensions; - - set extensions(dynamic extensions) => _extensions = extensions; - - dynamic get subBefore => _subBefore; - - set subBefore(dynamic subBefore) => _subBefore = subBefore; - - dynamic get subAfter => _subAfter; - - set subAfter(dynamic subAfter) => _subAfter = subAfter; - - String? get branch => _branch; - - set branch(String? branch) => _branch = branch; - - dynamic get pullType => _pullType; - - set pullType(dynamic pullType) => _pullType = pullType; - - dynamic get pullOption => _pullOption; - - set pullOption(dynamic pullOption) => _pullOption = pullOption; - - int? get pid => _pid; - - set pid(int? pid) => _pid = pid; - - int? get isDisabled => _isDisabled; - - set isDisabled(dynamic isDisabled) => _isDisabled = isDisabled; - - String? get logPath => _logPath; - - set logPath(String? logPath) => _logPath = logPath; - - String? get scheduleType => _scheduleType; - - set scheduleType(String? scheduleType) => _scheduleType = scheduleType; - - String? get alias => _alias; - - set alias(String? alias) => _alias = alias; - - String? get createdAt => _createdAt; - - set createdAt(String? createdAt) => _createdAt = createdAt; - - String? get updatedAt => _updatedAt; - - set updatedAt(String? updatedAt) => _updatedAt = updatedAt; - - Subscription.fromJson(Map json) { - _id = json['id']; - _name = json['name']; - _url = json['url']; - _schedule = json['schedule']; - _intervalSchedule = json['interval_schedule'] != null - ? new IntervalSchedule.fromJson(json['interval_schedule']) - : null; - _type = json['type']; - _whitelist = json['whitelist']; - _blacklist = json['blacklist']; - _status = json['status']; - _dependences = json['dependences']; - _extensions = json['extensions']; - _subBefore = json['sub_before']; - _subAfter = json['sub_after']; - _branch = json['branch']; - _pullType = json['pull_type']; - _pullOption = json['pull_option']; - _pid = json['pid']; - _isDisabled = json['is_disabled']; - _logPath = json['log_path']; - _scheduleType = json['schedule_type']; - _alias = json['alias']; - _createdAt = json['createdAt']; - _updatedAt = json['updatedAt']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this._id; - data['name'] = this._name; - data['url'] = this._url; - data['schedule'] = this._schedule; - if (this._intervalSchedule != null) { - data['interval_schedule'] = this._intervalSchedule!.toJson(); - } - data['type'] = this._type; - data['whitelist'] = this._whitelist; - data['blacklist'] = this._blacklist; - data['status'] = this._status; - data['dependences'] = this._dependences; - data['extensions'] = this._extensions; - data['sub_before'] = this._subBefore; - data['sub_after'] = this._subAfter; - data['branch'] = this._branch; - data['pull_type'] = this._pullType; - data['pull_option'] = this._pullOption; - data['pid'] = this._pid; - data['is_disabled'] = this._isDisabled; - data['log_path'] = this._logPath; - data['schedule_type'] = this._scheduleType; - data['alias'] = this._alias; - data['createdAt'] = this._createdAt; - data['updatedAt'] = this._updatedAt; - return data; - } - static Subscription jsonConversion(Map json) { - return Subscription.fromJson(json); - } -} - -class IntervalSchedule { - String? _type; - int? _value; - - IntervalSchedule({String? type, int? value}) { - if (type != null) { - this._type = type; - } - if (value != null) { - this._value = value; - } - } - - String? get type => _type; - - set type(String? type) => _type = type; - - int? get value => _value; - - set value(int? value) => _value = value; - - IntervalSchedule.fromJson(Map json) { - _type = json['type']; - _value = json['value']; - } - - Map toJson() { - final Map data = new Map(); - data['type'] = this._type; - data['value'] = this._value; - return data; - } - - -} diff --git a/lib/module/others/subscription/subscription_detail_page.dart b/lib/module/others/subscription/subscription_detail_page.dart deleted file mode 100644 index cb3b465..0000000 --- a/lib/module/others/subscription/subscription_detail_page.dart +++ /dev/null @@ -1,341 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_bean.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_time_log_page.dart'; - -import '../../../base/http/api.dart'; -import '../../../base/routes.dart'; -import '../../../base/theme.dart'; -import '../../task/task_viewmodel.dart'; - -class SubscriptionDetailPage extends StatefulWidget { - final Subscription bean; - final bool hideAppbar; - - const SubscriptionDetailPage(this.bean, {Key? key, this.hideAppbar = false}) - : super(key: key); - - @override - State createState() => _SubscriptionDetailPageState(); -} - -class _SubscriptionDetailPageState extends State { - - List actions = []; - - - @override - void initState() { - super.initState(); - //actions.clear(); - actions.addAll( - [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () async { - Navigator.of(context).pop(); - if (widget.bean.status! == 1) { - await startCron(context); - } else { - await stopCron(context); - } - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: Material( - color: Colors.transparent, - child: Text( - widget.bean.status! == 1 ? "运行" : "停止运行", - style: const TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - showLog(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "查看日志", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - - ], - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - title: "订阅管理", - canBack: true, - actions: [ - InkWell( - onTap: () { - showCupertinoModalPopup( - context: context, - builder: (context) { - return CupertinoActionSheet( - title: Container( - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "更多操作", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - actions: actions, - cancelButton: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: const Material( - color: Colors.transparent, - child: Text( - "取消", - style: TextStyle( - color: Colors.red, - fontSize: 16, - ), - ), - ), - ), - ), - ); - }); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - Icons.more_horiz, - color: Colors.white, - size: 26, - ), - ), - ), - ) - ], - ), - body: SingleChildScrollView( - primary: true, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TaskDetailCell( - title: "名称", - desc: widget.bean.name, - ), - TaskDetailCell( - title: "仓库类型", - desc: widget.bean.type == "public-repo" - ? "公开仓库" - : widget.bean.type == "private-repo" - ? "私有仓库" - : "单文件", - ), - TaskDetailCell( - title: "链接", - desc: widget.bean.url ?? "", - ), - TaskDetailCell( - title: "分支", - desc: widget.bean.branch ?? "", - ), - TaskDetailCell( - title: "定时类型", - desc: widget.bean.scheduleType ?? "", - ), - TaskDetailCell( - title: "定时规则", - desc: widget.bean.scheduleType == "crontab" - ? widget.bean.schedule ?? "" - : widget.bean.intervalSchedule!.type == "days" - ? "每" + widget.bean.intervalSchedule!.value.toString() + "天" - : widget.bean.intervalSchedule!.type == "hours" - ? "每" + - widget.bean.intervalSchedule!.value.toString() + - "小时" - : widget.bean.intervalSchedule!.type == "minutes" - ? "每" + - widget.bean.intervalSchedule!.value.toString() + - "分钟" - : "每" + - widget.bean.intervalSchedule!.value.toString() + - "秒", - ), - TaskDetailCell( - title: "白名单", - desc: widget.bean.whitelist ?? "", - ), - TaskDetailCell( - title: "黑名单", - desc: widget.bean.blacklist ?? "", - ), - TaskDetailCell( - title: "依赖文件", - desc: widget.bean.dependences ?? "", - ), - TaskDetailCell( - title: "文件后缀", - desc: widget.bean.extensions ?? "", - ), - TaskDetailCell( - title: "执行前", - desc: widget.bean.subAfter ?? "", - ), - TaskDetailCell( - title: "执行后", - desc: widget.bean.subBefore ?? "", - ), - ], - ), - ), - ); - } - - startCron(BuildContext context) async { - await Api.startSubscription([widget.bean.id!]); - setState(() {}); - showLog(); - } - - stopCron(BuildContext context) async { - await Api.stopSubscription([widget.bean.id!]); - setState(() {}); - } - - void showLog() { - showCupertinoModalBottomSheet( - expand: true, - context: context, - backgroundColor: Colors.transparent, - builder: (context) => - SubscriptionTimeLogPage( - widget.bean.id!, - true, - widget.bean.name ?? "", - ), - ); - } -} - -class TaskDetailCell extends ConsumerWidget { - final String title; - final String? desc; - final Widget? icon; - final bool hideDivide; - final Function? taped; - - const TaskDetailCell({ - Key? key, - required this.title, - this.desc, - this.icon, - this.hideDivide = false, - this.taped, - }) : super(key: key); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only( - top: 10, - left: 15, - right: 10, - bottom: 10, - ), - child: Row( - children: [ - Text( - title, - style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 16, - ), - ), - const SizedBox( - width: 30, - ), - desc != null - ? Expanded( - child: Align( - alignment: Alignment.centerRight, - child: SelectableText( - desc!, - textAlign: TextAlign.right, - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - onTap: () { - if (taped != null) { - taped!(); - } - }, - style: TextStyle( - color: - ref.watch(themeProvider).themeColor.descColor(), - fontSize: 14, - ), - ), - ), - ) - : Expanded( - child: - Align(alignment: Alignment.centerRight, child: icon!), - ), - ], - ), - ), - hideDivide - ? const SizedBox.shrink() - : const Divider( - indent: 15, - ), - ], - ); - } - - -} diff --git a/lib/module/others/subscription/subscription_page.dart b/lib/module/others/subscription/subscription_page.dart deleted file mode 100644 index 4286169..0000000 --- a/lib/module/others/subscription/subscription_page.dart +++ /dev/null @@ -1,329 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:highlight/languages/routeros.dart'; -import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_bean.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_time_log_page.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -import '../../../base/http/api.dart'; -import '../../../base/routes.dart'; -import '../../../base/theme.dart'; -import '../../../base/ui/empty_widget.dart'; -import '../../../base/ui/lazy_load_state.dart'; - -class SubscriptionPage extends ConsumerStatefulWidget { - const SubscriptionPage({Key? key}) : super(key: key); - - @override - _ScriptPageState createState() => _ScriptPageState(); -} - -class _ScriptPageState extends ConsumerState with LazyLoadState { - List list = []; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - title: "订阅管理", - canBack: true, - actions: [ - InkWell( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routerSubscriptionAdd, - ); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - CupertinoIcons.add, - size: 24, - color: Colors.white, - ), - ), - ), - ), - ], - ), - body: RefreshIndicator( - color: Theme.of(context).primaryColor, - onRefresh: () async { - return loadData(); - }, - child: list.isEmpty - ? const EmptyWidget() - : ListView.builder( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, - itemBuilder: (context, index) { - Subscription item = list[index]; - return SubscriptionCell(list[index], index, ref); - }, - itemCount: list.length, - ), - ), - ); - } - - Future loadData() async { - HttpResponse> response = await Api.getSubscription(); - - if (response.success) { - if (response.bean == null || response.bean!.isEmpty) { - "暂无数据".toast(); - } - list.clear(); - list.addAll(response.bean ?? []); - setState(() {}); - } else { - response.message?.toast(); - } - } - - @override - void onLazyLoad() { - loadData(); - } -} - -class SubscriptionCell extends StatelessWidget { - final Subscription bean; - final int index; - final WidgetRef ref; - - const SubscriptionCell(this.bean, this.index, this.ref, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ColoredBox( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - child: Slidable( - key: ValueKey(bean.id), - endActionPane: ActionPane( - motion: const StretchMotion(), - extentRatio: 0.7, - children: [ - SlidableAction( - backgroundColor: const Color(0xff5D5E70), - onPressed: (_) { - WidgetsBinding.instance.endOfFrame.then((timeStamp) { - Navigator.of(context).pushNamed(Routes.routerSubscriptionAdd, arguments: bean); - }); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.pencil_outline, - ), - SlidableAction( - backgroundColor: const Color(0xffA356D6), - onPressed: (_) { - changeSubscriptionEnable(); - }, - foregroundColor: Colors.white, - icon: bean.isDisabled == null || bean.isDisabled == 0 ? Icons.dnd_forwardslash : Icons.check_circle_outline_sharp, - ), - SlidableAction( - backgroundColor: const Color(0xffEA4D3E), - onPressed: (_) { - Api.deleteSubscription([bean.id!]); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.delete, - ), - ], - ), - startActionPane: ActionPane( - motion: const StretchMotion(), - extentRatio: 0.4, - children: [ - SlidableAction( - backgroundColor: const Color(0xffD25535), - onPressed: (_) { - changeSubscriptionStatus(); - }, - foregroundColor: Colors.white, - icon: bean.status! == 1 ? CupertinoIcons.memories : CupertinoIcons.stop_circle, - ), - SlidableAction( - backgroundColor: const Color(0xff606467), - onPressed: (_) { - Future.delayed( - const Duration( - milliseconds: 250, - ), () { - showLog(context); - }); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.text_justifyleft, - ), - ], - ), - child: InkWell( - onTap: () { - Navigator.of(context).pushNamed(Routes.routerSubscriptionDetail, arguments: bean); - }, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width, - color: Colors.transparent, - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 8, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - bean.status == 1 - ? const SizedBox.shrink() - : SizedBox( - width: 15, - height: 15, - child: CircularProgressIndicator( - strokeWidth: 2, - color: ref.watch(themeProvider).primaryColor, - ), - ), - SizedBox( - width: bean.status == 1 ? 0 : 5, - ), - Expanded( - child: Material( - color: Colors.transparent, - child: Text( - bean.name ?? "", - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 18, - ), - ), - ), - ), - ], - ), - ), - Material( - color: Colors.transparent, - child: Text( - bean.branch!, - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - const SizedBox( - height: 8, - ), - Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - bean.isDisabled == 1 - ? const Icon( - Icons.dnd_forwardslash, - size: 12, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox( - width: 5, - ), - Material( - color: Colors.transparent, - child: Text( - bean.schedule ?? "", - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - const SizedBox( - height: 8, - ), - Material( - color: Colors.transparent, - child: Text( - bean.url ?? "", - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - ), - const Divider( - height: 1, - indent: 15, - ), - ], - ), - )), - ); - } - - void showLog(BuildContext context) { - showCupertinoModalBottomSheet( - expand: true, - context: context, - backgroundColor: Colors.transparent, - builder: (context) => SubscriptionTimeLogPage( - bean.id!, - true, - bean.name ?? "", - ), - ); - } - - Future changeSubscriptionStatus() async { - if (bean.status == null || bean.status == 0) { - await Api.stopSubscription([bean.id!]); - } else { - await Api.startSubscription([bean.id!]); - } - } - - Future changeSubscriptionEnable() async { - if (bean.isDisabled == null || bean.isDisabled == 0) { - await Api.disableSubscription([bean.id!]); - } else { - await Api.enableSubscription([bean.id!]); - } - } -} diff --git a/lib/module/others/subscription/subscription_time_log_page.dart b/lib/module/others/subscription/subscription_time_log_page.dart deleted file mode 100644 index fc47d1e..0000000 --- a/lib/module/others/subscription/subscription_time_log_page.dart +++ /dev/null @@ -1,181 +0,0 @@ -import 'dart:async'; -import 'dart:math'; -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:qinglong_app/module/others/subscription/subscription_page.dart'; -import 'package:share_plus/share_plus.dart'; - -import '../../../base/ui/lazy_load_state.dart'; - -class SubscriptionTimeLogPage extends StatefulWidget { - final int subId; - final bool needTimer; - final String title; - - const SubscriptionTimeLogPage(this.subId, this.needTimer, this.title, {Key? key}) - : super(key: key); - - @override - _SubscriptionTimeLogPageState createState() => _SubscriptionTimeLogPageState(); -} - -class _SubscriptionTimeLogPageState extends State - with LazyLoadState { - Timer? _timer; - - String? content; - - @override - void initState() { - super.initState(); - } - - bool isRequest = false; - bool canRequest = true; - - getLogData() async { - if (!canRequest) return; - if (isRequest) return; - isRequest = true; - HttpResponse response = await Api.subTimeLog(widget.subId); - if (response.success) { - content = response.bean; - setState(() {}); - } - isRequest = false; - } - - @override - void dispose() { - _timer?.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Material( - child: SafeArea( - child: Container( - color: Colors.white, - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - Row( - children: [ - const SizedBox( - width: 15, - ), - InkWell( - onTap: () { - Navigator.of(context).pop(); - }, - child: const Icon( - CupertinoIcons.chevron_down, - size: 18, - ), - ), - Expanded( - child: Center( - child: Text( - widget.title, - style: const TextStyle( - fontSize: 16, - ), - ), - ), - ), - InkWell( - onTap: () { - Share.share(content ?? ""); - }, - child: const Icon( - CupertinoIcons.share, - size: 16, - ), - ), - const SizedBox( - width: 15, - ), - ], - ), - const SizedBox( - height: 15, - ), - if (content == null) - const Expanded( - child: Center( - child: CupertinoActivityIndicator(), - ), - ) - else - Expanded( - child: SingleChildScrollView( - primary: true, - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SelectableText( - content!, - scrollPhysics: const NeverScrollableScrollPhysics(), - onSelectionChanged: (TextSelection selection, - SelectionChangedCause? cause) { - final int newStart = min( - selection.baseOffset, selection.extentOffset); - final int newEnd = max( - selection.baseOffset, selection.extentOffset); - if (newEnd == newStart) { - canRequest = true; - } else { - canRequest = false; - } - }, - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - style: const TextStyle( - fontSize: 12, - ), - ), - const SizedBox( - height: 400, - ), - ], - ), - ), - ) - ], - ), - ), - ), - ); - } - - @override - void onLazyLoad() { - if (widget.needTimer) { - _timer = Timer.periodic( - const Duration(seconds: 2), - (timer) { - getLogData(); - }, - ); - } else { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - getLogData(); - }); - } - } -} \ No newline at end of file diff --git a/lib/module/others/task_log/task_log_bean.dart b/lib/module/others/task_log/task_log_bean.dart deleted file mode 100644 index f8cd536..0000000 --- a/lib/module/others/task_log/task_log_bean.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -/// @author NewTab -@JsonConversion() -class TaskLogBean { - String? name; - bool? isDir; - List? files; - List? children; - - TaskLogBean({this.name, this.files}); - - TaskLogBean.fromJson(Map json) { - name = json['name'] ?? json['title']; - isDir = json['isDir'] ?? (json['type'] == "directory"); - - files = json['files']?.cast(); - if (json['children'] != null) { - children = []; - json['children'].forEach((v) { - children!.add(Children.fromJson(v)); - }); - } - } - - Map toJson() { - final Map data = new Map(); - data['name'] = this.name; - data['files'] = this.files; - if (this.children != null) { - data['children'] = this.children!.map((v) => v.toJson()).toList(); - } - return data; - } - - static TaskLogBean jsonConversion(Map json) { - return TaskLogBean.fromJson(json); - } -} - -class Children { - String? title; - String? value; - String? type; - String? key; - String? parent; - - Children({this.title, this.value, this.type, this.key, this.parent}); - - Children.fromJson(Map json) { - title = json['title']; - value = json['value']; - type = json['type']; - key = json['key']; - parent = json['parent']; - } - - Map toJson() { - final Map data = new Map(); - data['title'] = this.title; - data['value'] = this.value; - data['type'] = this.type; - data['key'] = this.key; - data['parent'] = this.parent; - return data; - } -} diff --git a/lib/module/others/task_log/task_log_detail_page.dart b/lib/module/others/task_log/task_log_detail_page.dart deleted file mode 100644 index 93948e9..0000000 --- a/lib/module/others/task_log/task_log_detail_page.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/ui/lazy_load_state.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -/// @author NewTab -class TaskLogDetailPage extends ConsumerStatefulWidget { - final String title; - final String path; - - const TaskLogDetailPage({ - Key? key, - required this.title, - required this.path, - }) : super(key: key); - - @override - _TaskLogDetailPageState createState() => _TaskLogDetailPageState(); -} - -class _TaskLogDetailPageState extends ConsumerState - with LazyLoadState { - String? content; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: "任务日志详情", - ), - body: content == null - ? const Center(child: CupertinoActivityIndicator()) - : Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: SelectableText( - (content == null || content!.isEmpty) ? "暂无数据" : content!, - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - ), - ), - ); - } - - Future loadData() async { - HttpResponse response = await Api.taskLogDetail( - widget.title, - widget.path, - ); - - if (response.success) { - content = response.bean; - setState(() {}); - } else { - response.message?.toast(); - } - } - - @override - void onLazyLoad() { - loadData(); - } -} diff --git a/lib/module/others/task_log/task_log_page.dart b/lib/module/others/task_log/task_log_page.dart deleted file mode 100644 index d873c85..0000000 --- a/lib/module/others/task_log/task_log_page.dart +++ /dev/null @@ -1,181 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/lazy_load_state.dart'; -import 'package:qinglong_app/base/ui/search_cell.dart'; -import 'package:qinglong_app/module/others/task_log/task_log_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -/// @author NewTab -class TaskLogPage extends ConsumerStatefulWidget { - const TaskLogPage({Key? key}) : super(key: key); - - @override - _TaskLogPageState createState() => _TaskLogPageState(); -} - -class _TaskLogPageState extends ConsumerState - with LazyLoadState { - List list = []; - final TextEditingController _searchController = TextEditingController(); - - Widget searchCell(WidgetRef context) { - return Container( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 10, - ), - child: SearchCell( - controller: _searchController, - ), - ); - } - - @override - void initState() { - super.initState(); - _searchController.addListener(() { - setState(() {}); - }); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: "任务日志", - ), - body: list.isEmpty - ? const Center( - child: CupertinoActivityIndicator(), - ) - : ListView.builder( - itemBuilder: (context, index) { - if (index == 0) { - return searchCell(ref); - } - TaskLogBean item = list[index - 1]; - if (_searchController.text.isNotEmpty && - !(item.name?.contains(_searchController.text) ?? false)) { - return const SizedBox.shrink(); - } - return ColoredBox( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - child: (item.isDir ?? false) - ? ExpansionTile( - title: Text( - item.name ?? "", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - children: (item.files?.isNotEmpty ?? false) - ? item.files! - .map((e) => ListTile( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeTaskLogDetail, - arguments: { - "path": item.name, - "title": e, - }); - }, - title: Text( - e, - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 14, - ), - ), - )) - .toList() - : (item.children ?? []) - .map((e) => ListTile( - onTap: () { - Navigator.of(context).pushNamed( - Routes.routeTaskLogDetail, - arguments: { - "path": item.name, - "title": e.title, - }); - }, - title: Text( - e.title ?? "", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 14, - ), - ), - )) - .toList(), - ) - : ListTile( - onTap: () { - if (item.isDir ?? false) { - "该文件夹为空".toast(); - return; - } - Navigator.of(context).pushNamed( - Routes.routeTaskLogDetail, - arguments: { - "path": "", - "title": item.name, - }); - }, - title: Text( - item.name ?? "", - style: TextStyle( - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - ), - ); - }, - itemCount: list.length, - ), - ); - } - - Future loadData() async { - HttpResponse> response = await Api.taskLog(); - - if (response.success) { - if (response.bean == null || response.bean!.isEmpty) { - "暂无数据".toast(); - } - list.clear(); - list.addAll(response.bean ?? []); - setState(() {}); - } else { - response.message?.toast(); - } - } - - @override - void onLazyLoad() { - loadData(); - } -} diff --git a/lib/module/others/theme_page.dart b/lib/module/others/theme_page.dart deleted file mode 100644 index afdcbaa..0000000 --- a/lib/module/others/theme_page.dart +++ /dev/null @@ -1,482 +0,0 @@ -import 'dart:math'; - -import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/theme.dart'; - -class ThemePage extends ConsumerStatefulWidget { - const ThemePage({Key? key}) : super(key: key); - - @override - _ThemePageState createState() => _ThemePageState(); -} - -class _ThemePageState extends ConsumerState { - late Color _primaryColor; - List colors = []; - double colorHeight = 40; - double smallColorHeight = 8; - - @override - void initState() { - super.initState(); - _primaryColor = ref.read(themeProvider).primaryColor; - colors.add(commonColor); - colors.addAll([ - Colors.red, - Colors.pink, - Colors.purple, - Colors.deepPurple, - Colors.indigo, - Colors.blue, - Colors.lightBlue, - Colors.cyan, - Colors.teal, - Colors.green, - Colors.lightGreen, - Colors.lime, - Colors.yellow, - Colors.amber, - Colors.orange, - Colors.deepOrange, - Colors.brown, - Colors.blueGrey, - ]); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - backgroundColor: const Color(0xff999999), - appBar: QlAppBar( - title: '主题设置', - canBack: true, - actions: [ - InkWell( - onTap: () { - submit(); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "保存", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SafeArea( - bottom: true, - child: Column( - children: [ - const SizedBox( - height: 15, - ), - Expanded( - child: SizedBox( - height: - MediaQuery.of(context).size.height * 3 / 4 - kToolbarHeight, - child: Row( - children: [ - const SizedBox( - width: 20, - ), - Expanded( - child: ClipRRect( - borderRadius: BorderRadius.circular(15), - child: Scaffold( - appBar: AppBar( - backgroundColor: _primaryColor, - title: Text("示例页面"), - elevation: 0, - automaticallyImplyLeading: false, - centerTitle: true, - ), - body: ListView.builder( - itemBuilder: (context, index) { - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Container( - width: MediaQuery.of(context).size.width, - color: index == 0 - ? ref - .watch(themeProvider) - .themeColor - .pinColor() - : Colors.transparent, - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 8, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: - MainAxisAlignment.start, - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Expanded( - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Random().nextBool() - ? const SizedBox.shrink() - : SizedBox( - width: 15, - height: 15, - child: - CircularProgressIndicator( - strokeWidth: 2, - color: - _primaryColor, - ), - ), - SizedBox( - width: Random().nextBool() - ? 0 - : 5, - ), - Expanded( - child: Material( - color: Colors.transparent, - child: Text( - "示例名称", - maxLines: 1, - overflow: TextOverflow - .ellipsis, - style: TextStyle( - overflow: TextOverflow - .ellipsis, - color: ref - .watch( - themeProvider) - .themeColor - .titleColor(), - fontSize: 18, - ), - ), - ), - ), - ], - ), - ), - Material( - color: Colors.transparent, - child: Text( - "上午10:00", - maxLines: 1, - style: TextStyle( - overflow: - TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - const SizedBox( - height: 8, - ), - Row( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - Random().nextBool() - ? const Icon( - Icons.dnd_forwardslash, - size: 12, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox( - width: 5, - ), - Material( - color: Colors.transparent, - child: Text( - "10 1-12/2 * * *", - maxLines: 1, - style: TextStyle( - overflow: - TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - const SizedBox( - height: 8, - ), - Material( - color: Colors.transparent, - child: Text( - "task raw post.js", - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - ), - const Divider( - height: 1, - indent: 15, - ), - ], - ); - }, - itemCount: 100, - ), - ), - ), - ), - const SizedBox( - width: 20, - ), - ], - ), - ), - ), - const SizedBox( - height: 15, - ), - Container( - margin: const EdgeInsets.symmetric( - horizontal: 15, - ), - height: colorHeight + 20, - padding: const EdgeInsets.symmetric(vertical: 10), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(20), - ), - child: ListView.separated( - physics: BouncingScrollPhysics(), - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - scrollDirection: Axis.horizontal, - itemBuilder: (context, index) { - if (index == 0) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - pickColor(); - }, - child: SizedBox( - width: colorHeight, - height: colorHeight, - child: Stack( - children: [ - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[0], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - left: 0, - top: colorHeight / 4 - smallColorHeight / 2, - ), - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[1], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - left: 0, - bottom: colorHeight / 4 - smallColorHeight / 2, - ), - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[2], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - left: colorHeight / 2 - smallColorHeight / 2, - top: 0, - ), - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[3], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - right: 0, - top: colorHeight / 4 - smallColorHeight / 2, - ), - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[4], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - right: 0, - bottom: colorHeight / 4 - smallColorHeight / 2, - ), - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[5], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - left: colorHeight / 2 - smallColorHeight / 2, - bottom: 0, - ), - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[6], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - left: colorHeight / 2 - smallColorHeight / 2, - bottom: 0, - ), - Positioned( - child: Container( - width: smallColorHeight, - height: smallColorHeight, - decoration: BoxDecoration( - color: colors[7], - borderRadius: - BorderRadius.circular(smallColorHeight), - ), - ), - left: colorHeight / 2 - smallColorHeight / 2, - bottom: colorHeight / 2 - smallColorHeight / 2, - ), - ], - ), - ), - ); - } else { - index = index - 1; - - return GestureDetector( - onTap: () { - _primaryColor = colors[index]; - setState(() {}); - }, - child: SizedBox( - width: colorHeight, - height: colorHeight, - child: Container( - decoration: BoxDecoration( - color: colors[index], - borderRadius: BorderRadius.circular(colorHeight), - ), - ), - ), - ); - } - }, - itemCount: colors.length + 1, - separatorBuilder: (BuildContext context, int index) { - return const SizedBox( - width: 15, - ); - }, - ), - ), - ], - ), - ), - ); - } - - void pickColor() { - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - titlePadding: const EdgeInsets.all(0), - contentPadding: const EdgeInsets.all(0), - content: SingleChildScrollView( - child: ColorPicker( - pickerColor: _primaryColor, - onColorChanged: (color) { - _primaryColor = color; - setState(() {}); - }, - colorPickerWidth: 300, - pickerAreaHeightPercent: 0.7, - enableAlpha: false, - pickerAreaBorderRadius: const BorderRadius.only( - topLeft: Radius.circular(2), - topRight: Radius.circular(2), - ), - hexInputBar: false, - ), - ), - ); - }, - ); - } - - void submit() { - ref.read(themeProvider).changePrimaryColor(_primaryColor); - Navigator.of(context).pop(); - } -} diff --git a/lib/module/others/update_password_page.dart b/lib/module/others/update_password_page.dart deleted file mode 100644 index a9ce563..0000000 --- a/lib/module/others/update_password_page.dart +++ /dev/null @@ -1,212 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/module/task/task_viewmodel.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -import '../../main.dart'; - -class UpdatePasswordPage extends ConsumerStatefulWidget { - const UpdatePasswordPage({ - Key? key, - }) : super(key: key); - - @override - ConsumerState createState() => _UpdatePasswordPageState(); -} - -class _UpdatePasswordPageState extends ConsumerState { - final TextEditingController _nameController = TextEditingController(); - final TextEditingController _passwordController = TextEditingController(); - final TextEditingController _passwordAgainController = - TextEditingController(); - - FocusNode focusNode = FocusNode(); - - @override - void initState() { - super.initState(); - WidgetsBinding.instance.addPostFrameCallback( - (timeStamp) { - focusNode.requestFocus(); - }, - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: "修改用户名密码", - actions: [ - InkWell( - onTap: () { - submit(); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "用户名:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - focusNode: focusNode, - controller: _nameController, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入用户名", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "新密码:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - obscureText: true, - controller: _passwordController, - maxLines: 1, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入新密码", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "再次输入新密码:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - obscureText: true, - maxLines: 1, - controller: _passwordAgainController, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "再次输入新密码", - ), - autofocus: false, - ), - ], - ), - ), - ], - ), - ); - } - - void submit() async { - if (_nameController.text.isEmpty) { - "用户名不能为空".toast(); - return; - } - if (_passwordController.text.isEmpty || - _passwordAgainController.text.isEmpty) { - "密码不能为空".toast(); - return; - } - - if (_passwordAgainController.text != _passwordController.text) { - "两次输入的密码不一致".toast(); - return; - } - - commitReal(); - } - - void commitReal() async { - String name = _nameController.text; - String password = _passwordController.text; - HttpResponse response = - await Api.updatePassword(name, password); - - if (response.success) { - "更新成功".toast(); - - if (!getIt().useSecretLogined) { - getIt().updateUserName( - getIt().host ?? "", name, password, false); - } - Navigator.of(context) - .pushNamedAndRemoveUntil(Routes.routeLogin, (route) => false); - } else { - response.message.toast(); - } - } -} diff --git a/lib/module/task/add_task_page.dart b/lib/module/task/add_task_page.dart deleted file mode 100644 index 4aed39b..0000000 --- a/lib/module/task/add_task_page.dart +++ /dev/null @@ -1,224 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/module/task/task_viewmodel.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -class AddTaskPage extends ConsumerStatefulWidget { - final TaskBean? taskBean; - - const AddTaskPage({Key? key, this.taskBean}) : super(key: key); - - @override - ConsumerState createState() => _AddTaskPageState(); -} - -class _AddTaskPageState extends ConsumerState { - late TaskBean taskBean; - - final TextEditingController _nameController = TextEditingController(); - final TextEditingController _commandController = TextEditingController(); - final TextEditingController _cronController = TextEditingController(); - - FocusNode focusNode = FocusNode(); - - @override - void initState() { - super.initState(); - if (widget.taskBean != null) { - taskBean = widget.taskBean!; - _nameController.text = taskBean.name ?? ""; - _commandController.text = taskBean.command ?? ""; - _cronController.text = taskBean.schedule ?? ""; - } else { - taskBean = TaskBean(); - } - WidgetsBinding.instance.addPostFrameCallback( - (timeStamp) { - focusNode.requestFocus(); - }, - ); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: taskBean.name == null ? "新增任务" : "编辑任务", - actions: [ - InkWell( - onTap: () { - submit(); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Text( - "提交", - style: TextStyle( - color: Colors.white, - fontSize: 16, - ), - ), - ), - ), - ) - ], - ), - body: SingleChildScrollView( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "名称:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - focusNode: focusNode, - controller: _nameController, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入名称", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "命令:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _commandController, - maxLines: 4, - minLines: 1, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入命令", - ), - autofocus: false, - ), - ], - ), - ), - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 15, - ), - const Text( - "定时:", - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.w600, - ), - ), - TextField( - controller: _cronController, - decoration: const InputDecoration( - contentPadding: EdgeInsets.fromLTRB(0, 5, 0, 5), - hintText: "请输入定时", - ), - autofocus: false, - ), - const SizedBox( - height: 5, - ), - const Text( - "定时的cron不校验是否正确", - style: TextStyle( - fontSize: 12, - ), - ), - ], - ), - ), - ], - ), - ), - ); - } - - void submit() async { - if (_nameController.text.isEmpty) { - "任务名称不能为空".toast(); - return; - } - if (_commandController.text.isEmpty) { - "命令不能为空".toast(); - return; - } - if (_cronController.text.isEmpty) { - "定时不能为空".toast(); - return; - } - - commitReal(); - } - - void commitReal() async { - taskBean.name = _nameController.text; - taskBean.command = _commandController.text; - taskBean.schedule = _cronController.text; - HttpResponse response = await Api.addTask( - _nameController.text, - _commandController.text, - _cronController.text, - id: taskBean.id, - ); - - if (response.success) { - (widget.taskBean?.sId == null) ? "新增成功" : "修改成功".toast(); - ref.read(taskProvider).updateBean(taskBean); - Navigator.of(context).pop(); - } else { - response.message.toast(); - } - } -} diff --git a/lib/module/task/intime_log/intime_log_page.dart b/lib/module/task/intime_log/intime_log_page.dart deleted file mode 100644 index 1b2b80e..0000000 --- a/lib/module/task/intime_log/intime_log_page.dart +++ /dev/null @@ -1,173 +0,0 @@ -import 'dart:async'; -import 'dart:math'; -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/ui/lazy_load_state.dart'; -import 'package:share_plus/share_plus.dart'; - -class InTimeLogPage extends StatefulWidget { - final String cronId; - final bool needTimer; - final String title; - - const InTimeLogPage(this.cronId, this.needTimer, this.title, {Key? key}) - : super(key: key); - - @override - _InTimeLogPageState createState() => _InTimeLogPageState(); -} - -class _InTimeLogPageState extends State - with LazyLoadState { - Timer? _timer; - - String? content; - - @override - void initState() { - super.initState(); - } - - bool isRequest = false; - bool canRequest = true; - - getLogData() async { - if (!canRequest) return; - if (isRequest) return; - isRequest = true; - HttpResponse response = await Api.inTimeLog(widget.cronId); - if (response.success) { - content = response.bean; - setState(() {}); - } - isRequest = false; - } - - @override - void dispose() { - _timer?.cancel(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return Scaffold( - body: SafeArea( - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: Column( - mainAxisSize: MainAxisSize.max, - children: [ - Row( - children: [ - const SizedBox( - width: 15, - ), - InkWell( - onTap: () { - Navigator.of(context).pop(); - }, - child: const Icon( - CupertinoIcons.chevron_down, - size: 18, - ), - ), - Expanded( - child: Center( - child: Text( - widget.title, - style: const TextStyle( - fontSize: 16, - ), - ), - ), - ), - InkWell( - onTap: () { - Share.share(content ?? ""); - }, - child: const Icon( - CupertinoIcons.share, - size: 16, - ), - ), - const SizedBox( - width: 15, - ), - ], - ), - const SizedBox( - height: 15, - ), - if (content == null) - const Expanded( - child: Center( - child: CupertinoActivityIndicator(), - ), - ) - else - Expanded( - child: SingleChildScrollView( - primary: true, - padding: const EdgeInsets.symmetric(horizontal: 15), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SelectableText( - content!, - scrollPhysics: const NeverScrollableScrollPhysics(), - onSelectionChanged: (TextSelection selection, - SelectionChangedCause? cause) { - final int newStart = min( - selection.baseOffset, selection.extentOffset); - final int newEnd = max( - selection.baseOffset, selection.extentOffset); - if (newEnd == newStart) { - canRequest = true; - } else { - canRequest = false; - } - }, - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - style: const TextStyle( - fontSize: 12, - ), - ), - const SizedBox( - height: 400, - ), - ], - ), - ), - ) - ], - ), - ), - ), - ); - } - - @override - void onLazyLoad() { - if (widget.needTimer) { - _timer = Timer.periodic( - const Duration(seconds: 2), - (timer) { - getLogData(); - }, - ); - getLogData(); - } else { - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - getLogData(); - }); - } - } -} diff --git a/lib/module/task/task_bean.dart b/lib/module/task/task_bean.dart deleted file mode 100644 index 02faf57..0000000 --- a/lib/module/task/task_bean.dart +++ /dev/null @@ -1,95 +0,0 @@ -import 'dart:convert'; - -import 'package:json_conversion_annotation/json_conversion_annotation.dart'; - -import '../../main.dart'; - -@JsonConversion() -class TaskBean { - String? name; - String? command; - String? schedule; - bool? saved; - String? sId; - int? id; - String? _id; - int? created; - int? status; - String? timestamp; - int? isSystem; - int? isDisabled; - String? logPath; - int? isPinned; - int? lastExecutionTime; - int? lastRunningTime; - String? pid; - - TaskBean( - {this.name, - this.command, - this.schedule, - this.saved, - this.sId, - this.created, - this.status, - this.timestamp, - this.isSystem, - this.isDisabled, - this.logPath, - this.isPinned, - this.lastExecutionTime, - this.lastRunningTime, - this.pid}); - - get nId => _id; - - TaskBean.fromJson(Map json) { - try { - name = json['name'].toString(); - command = json['command'].toString(); - schedule = json['schedule'].toString(); - saved = json['saved']; - id = json['id']; - _id = json['_id']; - sId = json.containsKey('_id') - ? json['_id'].toString() - : (json.containsKey('id') ? json['id'].toString() : ""); - created = int.tryParse(json['created'].toString()); - status = json['status']; - timestamp = json['timestamp'].toString(); - isSystem = json['isSystem']; - isDisabled = json['isDisabled']; - logPath = json['log_path'].toString(); - isPinned = json['isPinned']; - lastExecutionTime = int.tryParse(json['last_execution_time'].toString()); - lastRunningTime = json['last_running_time']; - pid = json['pid'].toString(); - } catch (e) { - logger.e(e); - } - } - - Map toJson() { - final Map data = new Map(); - data['name'] = this.name; - data['command'] = this.command; - data['schedule'] = this.schedule; - data['saved'] = this.saved; - data['_id'] = this.sId; - data['created'] = this.created; - data['status'] = this.status; - data['timestamp'] = this.timestamp; - data['isSystem'] = this.isSystem; - data['isDisabled'] = this.isDisabled; - data['log_path'] = this.logPath; - data['isPinned'] = this.isPinned; - data['last_execution_time'] = this.lastExecutionTime; - data['last_running_time'] = this.lastRunningTime; - data['pid'] = this.pid; - return data; - } - - static TaskBean jsonConversion(Map json) { - return TaskBean.fromJson(json); - } -} diff --git a/lib/module/task/task_detail/task_detail_page.dart b/lib/module/task/task_detail/task_detail_page.dart deleted file mode 100644 index 083c7e6..0000000 --- a/lib/module/task/task_detail/task_detail_page.dart +++ /dev/null @@ -1,508 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; -import 'package:qinglong_app/base/ql_app_bar.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/module/task/intime_log/intime_log_page.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/utils/utils.dart'; - -import '../task_viewmodel.dart'; - -class TaskDetailPage extends ConsumerStatefulWidget { - final TaskBean taskBean; - final bool hideAppbar; - - const TaskDetailPage(this.taskBean, {Key? key, this.hideAppbar = false}) - : super(key: key); - - @override - _TaskDetailPageState createState() => _TaskDetailPageState(); -} - -class _TaskDetailPageState extends ConsumerState { - List actions = []; - - @override - void initState() { - super.initState(); - } - - @override - Widget build(BuildContext context) { - Widget body = Material( - color: Colors.transparent, - child: Container( - color: Theme.of(context).scaffoldBackgroundColor, - child: SingleChildScrollView( - child: Column( - children: [ - Container( - margin: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 15, - ), - padding: const EdgeInsets.only( - top: 10, - bottom: 10, - ), - decoration: BoxDecoration( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - borderRadius: BorderRadius.circular(15), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TaskDetailCell( - title: "名称", - desc: widget.taskBean.name ?? "", - ), - TaskDetailCell( - title: "ID", - desc: widget.taskBean.sId ?? "", - ), - TaskDetailCell( - title: "任务", - desc: widget.taskBean.command ?? "", - ), - TaskDetailCell( - title: "创建时间", - desc: - Utils.formatMessageTime(widget.taskBean.created ?? 0), - ), - TaskDetailCell( - title: "更新时间", - desc: - Utils.formatGMTTime(widget.taskBean.timestamp ?? ""), - ), - TaskDetailCell( - title: "任务定时", - desc: widget.taskBean.schedule ?? "", - ), - TaskDetailCell( - title: "最后运行时间", - desc: Utils.formatMessageTime( - widget.taskBean.lastExecutionTime ?? 0), - ), - TaskDetailCell( - title: "最后运行时长", - desc: widget.taskBean.lastRunningTime == null - ? "-" - : "${widget.taskBean.lastRunningTime ?? "-"}秒", - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - showLog(); - }, - child: TaskDetailCell( - title: "日志路径", - desc: widget.taskBean.logPath ?? "-", - taped: () { - showLog(); - }, - ), - ), - TaskDetailCell( - title: "运行状态", - desc: widget.taskBean.status == 0 ? "正在运行" : "空闲", - ), - TaskDetailCell( - title: "脚本状态", - desc: widget.taskBean.isDisabled == 1 ? "已禁用" : "已启用", - ), - TaskDetailCell( - title: "是否置顶", - desc: widget.taskBean.isPinned == 1 ? "已置顶" : "未置顶", - hideDivide: true, - ), - ], - ), - ), - widget.hideAppbar - ? const SizedBox.shrink() - : SizedBox( - width: MediaQuery.of(context).size.width - 80, - child: CupertinoButton( - padding: const EdgeInsets.symmetric( - vertical: 5, - ), - color: Colors.red, - child: const Text( - "删 除", - style: TextStyle( - fontSize: 16, - ), - ), - onPressed: () { - delTask(context, ref); - }), - ), - const SizedBox( - height: 15, - ), - ], - ), - ), - ), - ); - - if (widget.hideAppbar) { - return body; - } - - actions.clear(); - actions.addAll( - [ - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () async { - Navigator.of(context).pop(); - if (widget.taskBean.status! == 1) { - await startCron(context, ref); - } else { - await stopCron(context, ref); - } - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: Material( - color: Colors.transparent, - child: Text( - widget.taskBean.status! == 1 ? "运行" : "停止运行", - style: const TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - showLog(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "查看日志", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - Navigator.of(context) - .pushNamed(Routes.routeAddTask, arguments: widget.taskBean); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "编辑", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - pinTask(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - color: Colors.transparent, - alignment: Alignment.center, - child: Material( - color: Colors.transparent, - child: Text( - widget.taskBean.isPinned! == 0 ? "置顶" : "取消置顶", - style: const TextStyle( - fontSize: 16, - ), - ), - ), - ), - ), - GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.of(context).pop(); - enableTask(); - }, - child: Container( - padding: const EdgeInsets.symmetric( - vertical: 15, - ), - alignment: Alignment.center, - child: Material( - color: Colors.transparent, - child: Text( - widget.taskBean.isDisabled! == 0 ? "禁用" : "启用", - style: const TextStyle( - color: Colors.red, - fontSize: 16, - ), - ), - ), - ), - ), - ], - ); - - return Scaffold( - appBar: QlAppBar( - canBack: true, - backCall: () { - Navigator.of(context).pop(); - }, - title: widget.taskBean.name ?? "", - actions: [ - InkWell( - onTap: () { - showCupertinoModalPopup( - context: context, - builder: (context) { - return CupertinoActionSheet( - title: Container( - alignment: Alignment.center, - child: const Material( - color: Colors.transparent, - child: Text( - "更多操作", - style: TextStyle( - fontSize: 16, - ), - ), - ), - ), - actions: actions, - cancelButton: GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () { - Navigator.pop(context); - }, - child: Container( - alignment: Alignment.center, - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: const Material( - color: Colors.transparent, - child: Text( - "取消", - style: TextStyle( - color: Colors.red, - fontSize: 16, - ), - ), - ), - ), - ), - ); - }); - }, - child: const Padding( - padding: EdgeInsets.symmetric( - horizontal: 15, - ), - child: Center( - child: Icon( - Icons.more_horiz, - color: Colors.white, - size: 26, - ), - ), - ), - ) - ], - ), - body: body, - ); - } - - startCron(BuildContext context, WidgetRef ref) async { - await ref.read(taskProvider).runCrons(widget.taskBean.sId!); - setState(() {}); - WidgetsBinding.instance.addPostFrameCallback((timeStamp) { - showLog(); - }); - } - - stopCron(BuildContext context, WidgetRef ref) async { - await ref.read(taskProvider).stopCrons(widget.taskBean.sId!); - setState(() {}); - } - - void enableTask() async { - await ref - .read(taskProvider) - .enableTask(widget.taskBean.sId!, widget.taskBean.isDisabled!); - setState(() {}); - } - - void pinTask() async { - await ref - .read(taskProvider) - .pinTask(widget.taskBean.sId!, widget.taskBean.isPinned!); - setState(() {}); - } - - void delTask(BuildContext context, WidgetRef ref) { - showCupertinoDialog( - context: context, - builder: (context) => CupertinoAlertDialog( - title: const Text("确认删除"), - content: Text("确认删除定时任务 ${widget.taskBean.name ?? ""} 吗"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () async { - Navigator.of(context).pop(); - await ref.read(taskProvider).delCron(widget.taskBean.sId!); - Navigator.of(context).pop(); - }, - ), - ], - ), - ); - } - - void showLog() { - showCupertinoModalBottomSheet( - expand: true, - context: context, - backgroundColor: Colors.transparent, - builder: (context) => InTimeLogPage( - widget.taskBean.sId!, - true, - widget.taskBean.name ?? "", - ), - ); - } -} - -class TaskDetailCell extends ConsumerWidget { - final String title; - final String? desc; - final Widget? icon; - final bool hideDivide; - final Function? taped; - - const TaskDetailCell({ - Key? key, - required this.title, - this.desc, - this.icon, - this.hideDivide = false, - this.taped, - }) : super(key: key); - - @override - Widget build(BuildContext context, WidgetRef ref) { - return Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.only( - top: 10, - left: 15, - right: 10, - bottom: 10, - ), - child: Row( - children: [ - Text( - title, - style: TextStyle( - color: ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 16, - ), - ), - const SizedBox( - width: 30, - ), - desc != null - ? Expanded( - child: Align( - alignment: Alignment.centerRight, - child: SelectableText( - desc!, - textAlign: TextAlign.right, - selectionHeightStyle: BoxHeightStyle.max, - selectionWidthStyle: BoxWidthStyle.max, - onTap: () { - if (taped != null) { - taped!(); - } - }, - style: TextStyle( - color: - ref.watch(themeProvider).themeColor.descColor(), - fontSize: 14, - ), - ), - ), - ) - : Expanded( - child: - Align(alignment: Alignment.centerRight, child: icon!), - ), - ], - ), - ), - hideDivide - ? const SizedBox.shrink() - : const Divider( - indent: 15, - ), - ], - ); - } -} diff --git a/lib/module/task/task_page.dart b/lib/module/task/task_page.dart deleted file mode 100644 index 390ed3d..0000000 --- a/lib/module/task/task_page.dart +++ /dev/null @@ -1,558 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:flutter_slidable/flutter_slidable.dart'; -import 'package:modal_bottom_sheet/modal_bottom_sheet.dart'; -import 'package:qinglong_app/base/base_state_widget.dart'; -import 'package:qinglong_app/base/routes.dart'; -import 'package:qinglong_app/base/theme.dart'; -import 'package:qinglong_app/base/ui/search_cell.dart'; -import 'package:qinglong_app/module/task/intime_log/intime_log_page.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/module/task/task_viewmodel.dart'; -import 'package:qinglong_app/utils/utils.dart'; - -class TaskPage extends ConsumerStatefulWidget { - const TaskPage({Key? key}) : super(key: key); - - @override - _TaskPageState createState() => _TaskPageState(); -} - -class _TaskPageState extends ConsumerState { - final TextEditingController _searchController = TextEditingController(); - - String currentState = TaskViewModel.allStr; - - @override - void initState() { - super.initState(); - - _searchController.addListener(() { - setState(() {}); - }); - } - - @override - Widget build(BuildContext context) { - return BaseStateWidget( - builder: (ref, model, child) { - return body(model, getListByType(model), ref); - }, - model: taskProvider, - onReady: (viewModel) { - viewModel.loadData(); - }, - ); - } - - Widget body(TaskViewModel model, List list, WidgetRef ref) { - return RefreshIndicator( - color: Theme.of(context).primaryColor, - onRefresh: () async { - return model.loadData(false); - }, - child: IconTheme( - data: const IconThemeData( - size: 25, - ), - child: SlidableAutoCloseBehavior( - child: ListView.separated( - keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag, - itemBuilder: (context, index) { - if (index == 0) { - return searchCell(ref); - } - TaskBean item = list[index - 1]; - if (_searchController.text.isEmpty || - (item.name - ?.toLowerCase() - .contains(_searchController.text.toLowerCase()) ?? - false) || - (item.command - ?.toLowerCase() - .contains(_searchController.text.toLowerCase()) ?? - false) || - (item.schedule - ?.contains(_searchController.text.toLowerCase()) ?? - false)) { - return TaskItemCell(item, ref); - } else { - return const SizedBox.shrink(); - } - }, - itemCount: list.length + 1, - separatorBuilder: (BuildContext context, int index) { - if (index == 0) return const SizedBox.shrink(); - TaskBean item = list[index - 1]; - if (_searchController.text.isEmpty || - (item.name - ?.toLowerCase() - .contains(_searchController.text.toLowerCase()) ?? - false) || - (item.command - ?.toLowerCase() - .contains(_searchController.text.toLowerCase()) ?? - false) || - (item.schedule - ?.contains(_searchController.text.toLowerCase()) ?? - false)) { - return Container( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - child: const Divider( - height: 1, - indent: 15, - ), - ); - } else { - return const SizedBox.shrink(); - } - }, - ), - ), - ), - ); - } - - Widget searchCell(WidgetRef context) { - return Container( - color: ref.watch(themeProvider).themeColor.settingBgColor(), - padding: const EdgeInsets.only( - left: 15, - ), - child: Row( - children: [ - Expanded( - child: Padding( - padding: const EdgeInsets.symmetric( - vertical: 10, - ), - child: SearchCell( - controller: _searchController, - ), - ), - ), - Material( - color: Colors.transparent, - child: PopupMenuButton( - onSelected: (String result) { - currentState = result; - setState(() {}); - }, - itemBuilder: (BuildContext context) => [ - PopupMenuItem( - child: Text( - TaskViewModel.allStr, - style: TextStyle( - color: currentState == TaskViewModel.allStr - ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 14, - ), - ), - value: TaskViewModel.allStr, - ), - PopupMenuItem( - child: Text( - TaskViewModel.runningStr, - style: TextStyle( - color: currentState == TaskViewModel.runningStr - ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 14, - ), - ), - value: TaskViewModel.runningStr, - ), - PopupMenuItem( - child: Text( - TaskViewModel.neverStr, - style: TextStyle( - color: currentState == TaskViewModel.neverStr - ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), - fontSize: 14, - ), - ), - value: TaskViewModel.neverStr, - ), - PopupMenuItem( - child: Row( - children: [ - Text( - TaskViewModel.notScriptStr, - style: TextStyle( - color: currentState == TaskViewModel.notScriptStr - ? ref.watch(themeProvider).primaryColor - : ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 14, - ), - ), - ], - ), - value: TaskViewModel.notScriptStr, - ), - PopupMenuItem( - child: Text( - TaskViewModel.disableStr, - style: TextStyle( - fontSize: 14, - color: currentState == TaskViewModel.disableStr - ? ref.watch(themeProvider).primaryColor - : ref.watch(themeProvider).themeColor.titleColor(), - ), - ), - value: TaskViewModel.disableStr, - ), - ], - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 10, - ), - child: Text( - "筛选", - style: TextStyle( - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 14, - ), - ), - ), - ), - ), - ], - ), - ); - } - - List getListByType(TaskViewModel model) { - if (currentState == TaskViewModel.allStr) { - return model.list; - } - - if (currentState == TaskViewModel.runningStr) { - return model.running; - } - - if (currentState == TaskViewModel.neverStr) { - return model.neverRunning; - } - if (currentState == TaskViewModel.notScriptStr) { - return model.notScripts; - } - if (currentState == TaskViewModel.disableStr) { - return model.disabled; - } - return model.list; - } -} - -class TaskItemCell extends StatelessWidget { - final TaskBean bean; - final WidgetRef ref; - - const TaskItemCell(this.bean, this.ref, {Key? key}) : super(key: key); - - @override - Widget build(BuildContext context) { - return ColoredBox( - color: bean.isPinned == 1 - ? ref.watch(themeProvider).themeColor.pinColor() - : ref.watch(themeProvider).themeColor.settingBgColor(), - child: Slidable( - key: ValueKey(bean.sId), - endActionPane: ActionPane( - motion: const StretchMotion(), - extentRatio: 0.7, - children: [ - SlidableAction( - backgroundColor: const Color(0xff5D5E70), - onPressed: (_) { - WidgetsBinding.instance.endOfFrame.then((timeStamp) { - Navigator.of(context) - .pushNamed(Routes.routeAddTask, arguments: bean); - }); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.pencil_outline, - ), - SlidableAction( - backgroundColor: const Color(0xffF19A39), - onPressed: (_) { - pinTask(context); - }, - foregroundColor: Colors.white, - icon: (bean.isPinned ?? 0) == 0 - ? CupertinoIcons.pin - : CupertinoIcons.pin_slash, - ), - SlidableAction( - backgroundColor: const Color(0xffA356D6), - onPressed: (_) { - enableTask(context); - }, - foregroundColor: Colors.white, - icon: bean.isDisabled! == 0 - ? Icons.dnd_forwardslash - : Icons.check_circle_outline_sharp, - ), - SlidableAction( - backgroundColor: const Color(0xffEA4D3E), - onPressed: (_) { - delTask(context, ref); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.delete, - ), - ], - ), - startActionPane: ActionPane( - motion: const StretchMotion(), - extentRatio: 0.4, - children: [ - SlidableAction( - backgroundColor: const Color(0xffD25535), - onPressed: (_) { - if (bean.status! == 1) { - startCron( - context, - ref, - ); - } else { - stopCron( - context, - ref, - ); - } - }, - foregroundColor: Colors.white, - icon: bean.status! == 1 - ? CupertinoIcons.memories - : CupertinoIcons.stop_circle, - ), - SlidableAction( - backgroundColor: const Color(0xff606467), - onPressed: (_) { - Future.delayed( - const Duration( - milliseconds: 250, - ), () { - logCron(context, ref); - }); - }, - foregroundColor: Colors.white, - icon: CupertinoIcons.text_justifyleft, - ), - ], - ), - child: Material( - color: bean.isPinned == 1 - ? ref.watch(themeProvider).themeColor.pinColor() - : ref.watch(themeProvider).themeColor.settingBgColor(), - child: InkWell( - onTap: () { - Navigator.of(context) - .pushNamed(Routes.routeTaskDetail, arguments: bean); - }, - child: Container( - width: MediaQuery.of(context).size.width, - color: Colors.transparent, - padding: const EdgeInsets.symmetric( - horizontal: 15, - vertical: 8, - ), - child: Column( - mainAxisSize: MainAxisSize.min, - mainAxisAlignment: MainAxisAlignment.start, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - ConstrainedBox( - constraints: BoxConstraints.loose( - Size.fromWidth( - MediaQuery.of(context).size.width / 2, - ), - ), - child: Material( - color: Colors.transparent, - child: Text( - bean.name ?? "", - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref - .watch(themeProvider) - .themeColor - .titleColor(), - fontSize: 16, - ), - ), - ), - ), - const SizedBox( - width: 7, - ), - bean.status == 0 - ? Image.asset( - "assets/images/icon_running.png", - fit: BoxFit.cover, - width: 45, - ) - : Image.asset( - "assets/images/icon_idle.png", - fit: BoxFit.cover, - width: 45, - ), - const SizedBox( - width: 7, - ), - bean.isDisabled == 1 - ? Image.asset( - "assets/images/icon_task_disable.png", - fit: BoxFit.cover, - width: 45, - ) - : const SizedBox.shrink() - ], - ), - ), - Material( - color: Colors.transparent, - child: Text( - (bean.lastExecutionTime == null || - bean.lastExecutionTime == 0) - ? "-" - : Utils.formatMessageTime( - bean.lastExecutionTime!), - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: - ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - const SizedBox( - height: 5, - ), - Material( - color: Colors.transparent, - child: Text( - bean.schedule ?? "", - maxLines: 1, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - const SizedBox( - height: 5, - ), - Material( - color: Colors.transparent, - child: Text( - bean.command ?? "", - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - overflow: TextOverflow.ellipsis, - color: ref.watch(themeProvider).themeColor.descColor(), - fontSize: 12, - ), - ), - ), - ], - ), - ), - ), - ), - ), - ); - } - - startCron(BuildContext context, WidgetRef ref) async { - await ref.read(taskProvider).runCrons(bean.sId!); - Future.delayed(const Duration(milliseconds: 250), () { - logCron(context, ref); - }); - } - - stopCron(BuildContext context, WidgetRef ref) { - ref.read(taskProvider).stopCrons(bean.sId!); - } - - logCron(BuildContext context, WidgetRef ref) { - showCupertinoModalBottomSheet( - expand: true, - context: context, - backgroundColor: Colors.transparent, - builder: (context) => InTimeLogPage( - bean.sId!, - true, - bean.name ?? "", - ), - ); - } - - void enableTask(BuildContext context) { - ref.read(taskProvider).enableTask(bean.sId!, bean.isDisabled!); - } - - void pinTask(BuildContext context) { - ref.read(taskProvider).pinTask(bean.sId!, bean.isPinned!); - } - - void delTask(BuildContext context, WidgetRef ref) { - showCupertinoDialog( - context: context, - useRootNavigator: false, - builder: (context) => CupertinoAlertDialog( - title: const Text("确认删除"), - content: Text("确认删除定时任务 ${bean.name ?? ""} 吗"), - actions: [ - CupertinoDialogAction( - child: const Text( - "取消", - style: TextStyle( - color: Color(0xff999999), - ), - ), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - CupertinoDialogAction( - child: Text( - "确定", - style: TextStyle( - color: ref.watch(themeProvider).primaryColor, - ), - ), - onPressed: () { - Navigator.of(context).pop(); - ref.watch(taskProvider.notifier).delCron(bean.sId!); - }, - ), - ], - ), - ); - } -} diff --git a/lib/module/task/task_viewmodel.dart b/lib/module/task/task_viewmodel.dart deleted file mode 100644 index 48ec5ed..0000000 --- a/lib/module/task/task_viewmodel.dart +++ /dev/null @@ -1,217 +0,0 @@ -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:qinglong_app/base/base_viewmodel.dart'; -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/module/task/task_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -var taskProvider = ChangeNotifierProvider((ref) => TaskViewModel()); - -class TaskViewModel extends BaseViewModel { - static const String allStr = "全部脚本"; - static const String runningStr = "正在运行"; - static const String neverStr = "从未运行"; - static const String notScriptStr = "拉库脚本"; - static const String disableStr = "禁用脚本"; - List list = []; - List running = []; - List neverRunning = []; - List notScripts = []; - List disabled = []; - - Future loadData([isLoading = true]) async { - if (isLoading && list.isEmpty) { - loading(notify: true); - } - - HttpResponse> result = await Api.crons(); - - if (result.success && result.bean != null) { - list.clear(); - list.addAll(result.bean!); - sortList(); - success(); - } else { - list.clear(); - failed(result.message, notify: true); - } - } - - void sortList() { - List p = []; - List r = []; - List d = []; - - for (int i = 0; i < list.length; i++) { - if (list[i].isPinned == 1) { - p.add(list.removeAt(i)); - i--; - continue; - } - - if (list[i].status == 0) { - r.add(list.removeAt(i)); - i--; - continue; - } - if (list[i].isDisabled == 1) { - d.add(list.removeAt(i)); - i--; - continue; - } - } - - p.sort((TaskBean a, TaskBean b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) - .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); - if (c == true) { - return 1; - } - return -1; - }); - - p.sort((a, b) { - return (a.isDisabled ?? 0) - (b.isDisabled ?? 0); - }); - - p.sort((a, b) { - if (a.status == 0 && b.status == 0) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) - .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); - if (c == true) { - return 1; - } - return -1; - } else { - return (a.status ?? 0) - (b.status ?? 0); - } - }); - - r.sort((a, b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) - .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); - if (c == true) { - return 1; - } - return -1; - }); - - d.sort((a, b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) - .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); - if (c == true) { - return 1; - } - return -1; - }); - - list.sort((a, b) { - bool c = DateTime.fromMillisecondsSinceEpoch(a.created ?? 0) - .isBefore(DateTime.fromMillisecondsSinceEpoch(b.created ?? 0)); - if (c == true) { - return 1; - } - return -1; - }); - - list.insertAll(0, r); - list.insertAll(0, p); - list.addAll(d); - - running.clear(); - running.addAll(list.where((element) => element.status == 0)); - neverRunning.clear(); - neverRunning - .addAll(list.where((element) => element.lastRunningTime == null)); - notScripts.clear(); - notScripts.addAll(list.where((element) => (element.command != null && - (element.command!.startsWith("ql repo") || - element.command!.startsWith("ql raw"))))); - disabled.clear(); - disabled.addAll(list.where((element) => element.isDisabled == 1)); - } - - Future runCrons(String cron) async { - HttpResponse result = await Api.startTasks([cron]); - if (result.success) { - loadData(false); - } else { - failToast(result.message, notify: true); - } - } - - Future stopCrons(String cron) async { - HttpResponse result = await Api.stopTasks([cron]); - if (result.success) { - loadData(false); - } else { - failToast(result.message, notify: true); - } - } - - Future delCron(String id) async { - HttpResponse result = await Api.delTask(id); - if (result.success) { - "删除成功".toast(); - loadData(false); - } else { - failToast(result.message, notify: true); - } - } - - void updateBean(TaskBean result) { - if (result.sId == null) { - loadData(false); - return; - } - TaskBean bean = list.firstWhere((element) => element.sId == result.sId); - bean.name = result.name; - bean.schedule = result.schedule; - bean.command = result.command; - notifyListeners(); - } - - Future pinTask(String sId, int isPinned) async { - if (isPinned == 1) { - HttpResponse response = await Api.unpinTask(sId); - - if (response.success) { - "取消置顶成功".toast(); - loadData(false); - } else { - failToast(response.message, notify: true); - } - } else { - HttpResponse response = await Api.pinTask(sId); - - if (response.success) { - "置顶成功".toast(); - loadData(false); - } else { - failToast(response.message, notify: true); - } - } - } - - Future enableTask(String sId, int isDisabled) async { - if (isDisabled == 0) { - HttpResponse response = await Api.disableTask(sId); - - if (response.success) { - "禁用成功".toast(); - loadData(false); - } else { - failToast(response.message, notify: true); - } - } else { - HttpResponse response = await Api.enableTask(sId); - - if (response.success) { - "启用成功".toast(); - loadData(false); - } else { - failToast(response.message, notify: true); - } - } - } -} diff --git a/lib/utils/codeeditor_theme.dart b/lib/utils/codeeditor_theme.dart deleted file mode 100644 index 564e173..0000000 --- a/lib/utils/codeeditor_theme.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'package:flutter/material.dart'; - -const qinglongLightTheme = { - 'root': - TextStyle(color: Color(0xff333333), backgroundColor: Color(0xffffffff)), - 'comment': TextStyle(color: Color(0xff999988), fontStyle: FontStyle.italic), - 'quote': TextStyle(color: Color(0xff999988), fontStyle: FontStyle.italic), - 'keyword': TextStyle(color: Color(0xff333333), fontWeight: FontWeight.bold), - 'selector-tag': - TextStyle(color: Color(0xff333333), fontWeight: FontWeight.bold), - 'subst': TextStyle(color: Color(0xff333333), fontWeight: FontWeight.normal), - 'number': TextStyle(color: Color(0xff008080)), - 'literal': TextStyle(color: Color(0xff008080)), - 'variable': TextStyle(color: Color(0xff008080)), - 'template-variable': TextStyle(color: Color(0xff008080)), - 'string': TextStyle(color: Color(0xffdd1144)), - 'doctag': TextStyle(color: Color(0xffdd1144)), - 'title': TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold), - 'section': TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold), - 'selector-id': - TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold), - 'type': TextStyle(color: Color(0xff445588), fontWeight: FontWeight.bold), - 'tag': TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal), - 'name': TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal), - 'attribute': - TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal), - 'regexp': TextStyle(color: Color(0xff009926)), - 'link': TextStyle(color: Color(0xff009926)), - 'symbol': TextStyle(color: Color(0xff990073)), - 'bullet': TextStyle(color: Color(0xff990073)), - 'built_in': TextStyle(color: Color(0xff0086b3)), - 'builtin-name': TextStyle(color: Color(0xff0086b3)), - 'meta': TextStyle(color: Color(0xff999999), fontWeight: FontWeight.bold), - 'deletion': TextStyle(backgroundColor: Color(0xffffdddd)), - 'addition': TextStyle(backgroundColor: Color(0xffddffdd)), - 'emphasis': TextStyle(fontStyle: FontStyle.italic), - 'strong': TextStyle(fontWeight: FontWeight.bold), -}; - -const qinglongDarkTheme = { - 'root': TextStyle(color: Color(0xff333333), backgroundColor: Colors.black), - 'comment': TextStyle(color: Color(0xff999988), fontStyle: FontStyle.italic), - 'quote': TextStyle(color: Color(0xff999988), fontStyle: FontStyle.italic), - 'keyword': TextStyle(color: Color(0xff333333), fontWeight: FontWeight.bold), - 'selector-tag': - TextStyle(color: Color(0xff333333), fontWeight: FontWeight.bold), - 'subst': TextStyle(color: Color(0xff333333), fontWeight: FontWeight.normal), - 'number': TextStyle(color: Color(0xff008080)), - 'literal': TextStyle(color: Color(0xff008080)), - 'variable': TextStyle(color: Color(0xff008080)), - 'template-variable': TextStyle(color: Color(0xff008080)), - 'string': TextStyle(color: Color(0xffdd1144)), - 'doctag': TextStyle(color: Color(0xffdd1144)), - 'title': TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold), - 'section': TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold), - 'selector-id': - TextStyle(color: Color(0xff990000), fontWeight: FontWeight.bold), - 'type': TextStyle(color: Color(0xff445588), fontWeight: FontWeight.bold), - 'tag': TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal), - 'name': TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal), - 'attribute': - TextStyle(color: Color(0xff000080), fontWeight: FontWeight.normal), - 'regexp': TextStyle(color: Color(0xff009926)), - 'link': TextStyle(color: Color(0xff009926)), - 'symbol': TextStyle(color: Color(0xff990073)), - 'bullet': TextStyle(color: Color(0xff990073)), - 'built_in': TextStyle(color: Color(0xff0086b3)), - 'builtin-name': TextStyle(color: Color(0xff0086b3)), - 'meta': TextStyle(color: Color(0xff999999), fontWeight: FontWeight.bold), - 'deletion': TextStyle(backgroundColor: Color(0xffffdddd)), - 'addition': TextStyle(backgroundColor: Color(0xffddffdd)), - 'emphasis': TextStyle(fontStyle: FontStyle.italic), - 'strong': TextStyle(fontWeight: FontWeight.bold), -}; diff --git a/lib/utils/extension.dart b/lib/utils/extension.dart deleted file mode 100644 index 902c6fc..0000000 --- a/lib/utils/extension.dart +++ /dev/null @@ -1,27 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:fluttertoast/fluttertoast.dart'; - -import '../main.dart'; - -extension ContextExt on BuildContext { - T read(ProviderBase provider) { - return ProviderScope.containerOf(this, listen: false).read(provider); - } -} - -extension StringExt on String? { - void toast() { - if (this == null || this!.isEmpty) return; - Fluttertoast.showToast( - msg: this!, - toastLength: Toast.LENGTH_SHORT, - gravity: ToastGravity.CENTER, - timeInSecForIosWeb: 1, - ); - } - - void log() { - logger.i(this); - } -} diff --git a/lib/utils/login_helper.dart b/lib/utils/login_helper.dart deleted file mode 100644 index 7a05d18..0000000 --- a/lib/utils/login_helper.dart +++ /dev/null @@ -1,89 +0,0 @@ -import 'package:qinglong_app/base/http/api.dart'; -import 'package:qinglong_app/base/http/http.dart'; -import 'package:qinglong_app/base/userinfo_viewmodel.dart'; -import 'package:qinglong_app/module/login/login_bean.dart'; -import 'package:qinglong_app/utils/extension.dart'; - -import '../main.dart'; - -class LoginHelper { - static int success = 0; - static int failed = 1; - static int twiceLogin = 2; - bool useSecretLogin = false; - - final String host; - final String userName; - final String password; - final bool rememberPassword; - - LoginHelper(this.useSecretLogin, this.host, this.userName, this.password, - this.rememberPassword); - - Future login() async { - Http.clear(); - getIt().updateHost(host); - HttpResponse response; - - if (loginByUserName()) { - response = await Api.login(userName, password); - } else { - response = await Api.loginByClientId(userName, password); - } - if (response.success) { - loginSuccess(response, userName, password); - return success; - } else if (loginByUserName() && response.code == 401) { - //可能用户使用的是老版本qinglong - HttpResponse oldResponse = - await Api.loginOld(userName, password); - if (oldResponse.success) { - loginSuccess(oldResponse, userName, password); - return success; - } else { - (oldResponse.message ?? "请检查网络情况").toast(); - if (oldResponse.code == 420) { - return twiceLogin; - } else { - return failed; - } - } - } else { - (response.message ?? "请检查网络情况").toast(); - //420代表需要2步验证 - if (response.code == 420) { - return twiceLogin; - } else { - return failed; - } - } - } - - Future loginTwice(String code) async { - HttpResponse response = - await Api.loginTwo(userName, password, code); - if (response.success) { - loginSuccess(response, userName, password); - return success; - } else { - (response.message ?? "请检查网络情况").toast(); - return failed; - } - } - - void loginSuccess( - HttpResponse response, String userName, String password) { - getIt().updateToken(response.bean?.token ?? ""); - if (rememberPassword) { - getIt() - .updateUserName(host, userName, password, !loginByUserName()); - } else { - getIt() - .updateUserName(host, "", "", !loginByUserName()); - } - } - - bool loginByUserName() { - return !useSecretLogin; - } -} diff --git a/lib/utils/sp_utils.dart b/lib/utils/sp_utils.dart deleted file mode 100644 index 004766b..0000000 --- a/lib/utils/sp_utils.dart +++ /dev/null @@ -1,173 +0,0 @@ -import 'package:shared_preferences/shared_preferences.dart'; -import 'dart:async'; -import 'dart:convert'; -import 'package:synchronized/synchronized.dart'; - -class SpUtil { - static SpUtil? _singleton; - static SharedPreferences? _prefs; - static Lock _lock = Lock(); - - static Future getInstance() async { - if (_singleton == null) { - await _lock.synchronized(() async { - if (_singleton == null) { - var singleton = SpUtil._(); - await singleton._init(); - _singleton = singleton; - } - }); - } - return _singleton!; - } - - SpUtil._(); - - Future _init() async { - _prefs = await SharedPreferences.getInstance(); - } - - /// put object. - static Future? putObject(String key, Object value) { - if (_prefs == null) return null; - return _prefs!.setString(key, json.encode(value)); - } - - /// get obj. - static T? getObj(String key, T f(Map v), {T? defValue}) { - Map? map = getObject(key); - return map == null ? defValue : f(map); - } - - /// get object. - static Map? getObject(String key) { - if (_prefs == null) return null; - String? _data = _prefs!.getString(key); - return (_data == null || _data.isEmpty) ? null : json.decode(_data); - } - - /// put object list. - static Future? putObjectList(String key, List list) { - if (_prefs == null) return null; - List _dataList = list.map((value) { - return json.encode(value); - }).toList(); - return _prefs!.setStringList(key, _dataList); - } - - /// get obj list. - static List? getObjList(String key, T f(Map v), - {List defValue = const []}) { - List? dataList = getObjectList(key); - List? list = dataList?.map((value) { - return f(value); - }).toList(); - return list ?? defValue; - } - - /// get object list. - static List? getObjectList(String key) { - if (_prefs == null) return null; - List? dataLis = _prefs!.getStringList(key); - return dataLis?.map((value) { - Map _dataMap = json.decode(value); - return _dataMap; - }).toList(); - } - - /// get string. - static String getString(String key, {String defValue = ''}) { - if (_prefs == null) return defValue; - return _prefs!.getString(key) ?? defValue; - } - - /// put string. - static Future? putString(String key, String value) { - if (_prefs == null) return null; - return _prefs!.setString(key, value); - } - - /// get bool. - static bool getBool(String key, {bool defValue = false}) { - if (_prefs == null) return defValue; - return _prefs!.getBool(key) ?? defValue; - } - - /// put bool. - static Future? putBool(String key, bool value) { - if (_prefs == null) return null; - return _prefs!.setBool(key, value); - } - - /// get int. - static int getInt(String key, {int defValue = 0}) { - if (_prefs == null) return defValue; - return _prefs!.getInt(key) ?? defValue; - } - - /// put int. - static Future? putInt(String key, int value) { - if (_prefs == null) return null; - return _prefs!.setInt(key, value); - } - - /// get double. - static double getDouble(String key, {double defValue = 0.0}) { - if (_prefs == null) return defValue; - return _prefs!.getDouble(key) ?? defValue; - } - - /// put double. - static Future? putDouble(String key, double value) { - if (_prefs == null) return null; - return _prefs!.setDouble(key, value); - } - - /// get string list. - static List getStringList(String key, - {List defValue = const []}) { - if (_prefs == null) return defValue; - return _prefs!.getStringList(key) ?? defValue; - } - - /// put string list. - static Future? putStringList(String key, List value) { - if (_prefs == null) return null; - return _prefs!.setStringList(key, value); - } - - /// get dynamic. - static dynamic getDynamic(String key, {Object? defValue}) { - if (_prefs == null) return defValue; - return _prefs!.get(key) ?? defValue; - } - - /// have key. - static bool haveKey(String key) { - if (_prefs == null) return false; - return _prefs!.getKeys().contains(key); - } - - /// get keys. - static Set? getKeys() { - if (_prefs == null) return null; - return _prefs!.getKeys(); - } - - /// remove. - static Future? remove(String key) { - if (_prefs == null) return null; - return _prefs!.remove(key); - } - - /// clear. - static Future? clear() { - if (_prefs == null) return null; - return _prefs!.clear(); - } - - ///Sp is initialized. - static bool isInitialized() { - return _prefs != null; - } -} diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart deleted file mode 100644 index 4d11b56..0000000 --- a/lib/utils/utils.dart +++ /dev/null @@ -1,117 +0,0 @@ -import 'package:flutter/cupertino.dart'; -import 'package:intl/intl.dart'; - -import '../module/home/system_bean.dart'; - -class Utils { - static final SystemBean systemBean = SystemBean(); - - static bool isUpperVersion() { - return systemBean.isUpperVersion(); - } - - static bool isUpperVersion2_12_2() { - return systemBean.isUpperVersion2_12_2(); - } - - static bool isUpperVersion2_13_0() { - return systemBean.isUpperVersion2_13_0(); - } - - static void hideKeyBoard(BuildContext context) { - FocusScope.of(context).requestFocus(FocusNode()); - } - - static String formatGMTTime(String gmtTime) { - // "Wed Jan 12 2022 20:33:39 GMT+0800 (中国标准时间)" - try { - if (gmtTime.isEmpty) return "-"; - List splitedStr = gmtTime.split(" "); - - int year = int.parse(splitedStr[3]); - String time = splitedStr[4]; - List splitedTime = time.split(":"); - int hour = int.parse(splitedTime[0]); - int min = int.parse(splitedTime[1]); - int second = int.parse(splitedTime[2]); - - int day = int.parse(splitedStr[2]); - - String month = "01"; - - switch (splitedStr[1]) { - case "Jan": - month = "01"; - break; - case "Feb": - month = "02"; - break; - case "Mar": - month = "03"; - break; - case "Apr": - month = "04"; - break; - case "May": - month = "05"; - break; - case "Jun": - month = "06"; - break; - case "Jul": - month = "07"; - break; - case "Aug": - month = "08"; - break; - case "Sep": - month = "09"; - break; - case "Oct": - month = "10"; - break; - case "Nov": - month = "11"; - break; - case "Dec": - month = "12"; - break; - } - - var date = DateTime(year, int.parse(month), day, hour, min, second); - - return formatMessageTime(date.millisecondsSinceEpoch); - } catch (e) { - return "-"; - } - } - - static String formatMessageTime(int time) { - if (time == 0) { - return "-"; - } - DateTime current = DateTime.now(); - DateTime chatTime; - if (time.toString().length == 10) { - chatTime = DateTime.fromMillisecondsSinceEpoch(time * 1000); - } else { - chatTime = DateTime.fromMillisecondsSinceEpoch(time); - } - - if (current.year == chatTime.year) { - if (current.day == chatTime.day) { - if (chatTime.hour <= 12) { - return DateFormat("上午 H:mm").format(chatTime); - } else { - return DateFormat("下午 H:mm").format(chatTime); - } - } else if (chatTime.day == current.day - 1) { - return DateFormat("昨天 H:mm").format(chatTime); - } else { - return DateFormat("M/d H:mm").format(chatTime); - } - } else { - return DateFormat("yyyy/M/d HH:mm").format(chatTime); - } - } -} diff --git a/pub/code_field-master/.gitignore b/pub/code_field-master/.gitignore deleted file mode 100644 index 1985397..0000000 --- a/pub/code_field-master/.gitignore +++ /dev/null @@ -1,74 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -build/ - -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java - -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Flutter.podspec -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/Flutter/flutter_export_environment.sh -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 diff --git a/pub/code_field-master/.metadata b/pub/code_field-master/.metadata deleted file mode 100644 index 12f7851..0000000 --- a/pub/code_field-master/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# 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: c5a4b4029c0798f37c4a39b479d7cb75daa7b05c - channel: stable - -project_type: package diff --git a/pub/code_field-master/CHANGELOG.md b/pub/code_field-master/CHANGELOG.md deleted file mode 100644 index 80fbf5b..0000000 --- a/pub/code_field-master/CHANGELOG.md +++ /dev/null @@ -1,46 +0,0 @@ -## [1.0.0-1] - 2021-03-06 - -* Initial release - -## [1.0.0-4] - 2021-03-11 - -* Added horizontal scrolling support -* Added code modifiers -* Cleaner padding API - -## [1.0.0-6] - 2021-03-12 - -* Added a temporary fix for https://github.com/flutter/flutter/issues/77929 - -## [1.0.0-7] - 2021-03-12 - -* Added a rawText getter to CodeController - -## [1.0.0-9] - 2021-04-21 - -* Removed dependency on flutter_keyboard_visibility - -## [1.0.1-0] - 2021-05-22 - -* TextEditingController.buildTextSpan breaking change migration for flutter 2.2.0 - -## [1.0.1-1] - 2021-06-04 - -* Added wrap paramerter to disable horizontal scrolling - -## [1.0.1-2] - 2021-07-23 - -* Fixed highlight parsing on web (issue #11) - -## [1.0.2] - 2021-07-23 - -* removeChar & removeSelection methods added -* added onChange callback -* added enabled flag -* fixed middle dot issue - -## [1.0.3] - 2022-05-02 - -* added onTap to CodeField API -* fixed tab behavior in read-only mode -* added setCursor method to CodeController diff --git a/pub/code_field-master/LICENSE b/pub/code_field-master/LICENSE deleted file mode 100644 index 1c1ea5c..0000000 --- a/pub/code_field-master/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2021 Bertrand Bevillard - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file diff --git a/pub/code_field-master/README.md b/pub/code_field-master/README.md deleted file mode 100644 index 36dfbc1..0000000 --- a/pub/code_field-master/README.md +++ /dev/null @@ -1,242 +0,0 @@ -# CodeField - -A customizable code text field supporting syntax highlighting - -[![Pub](https://img.shields.io/pub/v/code_text_field.svg)](https://pub.dev/packages/code_text_field) -[![Website shields.io](https://img.shields.io/website-up-down-green-red/http/shields.io.svg)](https://bertrandbev.github.io/code_field/) -[![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://raw.githubusercontent.com/BertrandBev/code_field/master/LICENSE) -[![Awesome Flutter](https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square)](https://github.com/Solido/awesome-flutter) - - - -## Live demo - -A [live demo](https://bertrandbev.github.io/code_field/#/) showcasing a few language / theme combinations - -## Showcase - -The experimental VM [dlox](https://github.com/BertrandBev/dlox) uses **CodeField** in its [online editor](https://bertrandbev.github.io/dlox/#/) - - -## Features - -- Code highlight for 189 built-in languages with 90 themes thanks to [flutter_highlight](https://pub.dev/packages/flutter_highlight) -- Easy language highlight customization through the use of theme maps -- Fully customizable code field style through a TextField like API -- Handles horizontal/vertical scrolling and vertical expansion -- Supports code modifiers -- Works on Android, iOS, and Web - -Code modifiers help manage indents automatically - - - - -The editor is wrapped in a horizontal scrollable container to handle long lines - - - - - -## Installing - -In the `pubspec.yaml` of your flutter project, add the following dependency: - -```yaml -dependencies: - ... - code_text_field: -``` - -[latest version](https://pub.dev/packages/code_text_field/install) - -In your library add the following import: - -```dart -import 'package:code_text_field/code_field.dart'; -``` - - -## Simple example - -A CodeField widget works with a **CodeController** which dynamically parses the text input according to a language and renders it with a theme map - -```dart -import 'package:flutter/material.dart'; -import 'package:code_text_field/code_field.dart'; -// Import the language & theme -import 'package:highlight/languages/dart.dart'; -import 'package:flutter_highlight/themes/monokai-sublime.dart'; - -class CodeEditor extends StatefulWidget { - @override - _CodeEditorState createState() => _CodeEditorState(); -} - -class _CodeEditorState extends State { - CodeController? _codeController; - - @override - void initState() { - super.initState(); - final source = "void main() {\n print(\"Hello, world!\");\n}"; - // Instantiate the CodeController - _codeController = CodeController( - text: source, - language: dart, - theme: monokaiSublimeTheme, - ); - } - - @override - void dispose() { - _codeController?.dispose(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - return CodeField( - controller: _codeController!, - textStyle: TextStyle(fontFamily: 'SourceCode'), - ); - } -} -``` - - - -Here, the monospace font [Source Code Pro](https://fonts.google.com/specimen/Source+Code+Pro?preview.text_type=custom) has been added to the assets folder and to the [pubspec.yaml](https://github.com/BertrandBev/code_field/blob/master/example/pubspec.yaml) file - - -## Parser options - -On top of a language definition, world-wise styling can be specified in the **stringMap** field - -```dart -_codeController = CodeController( - //... - stringMap: { - "Hello": TextStyle(fontWeight: FontWeight.bold, color: Colors.red), - "world": TextStyle(fontStyle: FontStyle.italic, color: Colors.green), - }, -); -``` - - - -More complex regexes may also be used with the **patternMap**. When a language is used though, its regexes patterns take precedence over **patternMap** and **stringMap**. - -```dart -_codeController = CodeController( - //... - patternMap: { - r"\B#[a-zA-Z0-9]+\b": - TextStyle(fontWeight: FontWeight.bold, color: Colors.purpleAccent), - }, -); -``` - - - -Both **patternMap** and **stringMap** can be used without specifying a language - -```dart -_codeController = CodeController( - text: source, - patternMap: { - r'".*"': TextStyle(color: Colors.yellow), - r'[a-zA-Z0-9]+\(.*\)': TextStyle(color: Colors.green), - }, - stringMap: { - "void": TextStyle(fontWeight: FontWeight.bold, color: Colors.red), - "print": TextStyle(fontWeight: FontWeight.bold, color: Colors.blue), - }, -); -``` - - - - -## Code Modifiers - -Code modifiers can be created to react to special keystrokes. -The default modifiers handle tab to space & automatic indentation. Here's the implementation of the default **TabModifier** - -```dart -class TabModifier extends CodeModifier { - const TabModifier() : super('\t'); - - @override - TextEditingValue? updateString( - String text, TextSelection sel, EditorParams params) { - final tmp = replace(text, sel.start, sel.end, " " * params.tabSpaces); - return tmp; - } -} -``` - - -## API - -### CodeField - -```dart -CodeField({ -Key? key, - required this.controller, - this.minLines, - this.maxLines, - this.expands = false, - this.wrap = false, - this.background, - this.decoration, - this.textStyle, - this.padding = const EdgeInsets.symmetric(), - this.lineNumberStyle = const LineNumberStyle(), - this.enabled, - this.cursorColor, - this.textSelectionTheme, - this.lineNumberBuilder, - this.focusNode, - this.onTap, -}) -``` - -```dart -LineNumberStyle({ - this.width = 42.0, - this.textAlign = TextAlign.right, - this.margin = 10.0, - this.textStyle, - this.background, -}) -``` - -### CodeController - -```dart -CodeController({ - String? text, - this.language, - this.theme, - this.patternMap, - this.stringMap, - this.params = const EditorParams(), - this.modifiers = const [ - const IntendModifier(), - const CloseBlockModifier(), - const TabModifier(), - ], - this.onChange, -}) -``` - -## Limitations - -- Autocomplete disabling on android [doesn't work yet](https://github.com/flutter/flutter/issues/71679) -- The TextField cursor doesn't seem to be handling space inputs properly on the web platform. Pending [issue resolution](https://github.com/flutter/flutter/issues/77929). The flag `webSpaceFix` fixes it by swapping spaces with transparent middle points. - -## Notes - -A [breaking change](https://flutter.dev/docs/release/breaking-changes/buildtextspan-buildcontext) to the `TextEditingController` was introduced in flutter beta, dev & master channels. The branch [beta](https://github.com/BertrandBev/code_field/tree/beta) should comply with those changes. diff --git a/pub/code_field-master/code_field.code-workspace b/pub/code_field-master/code_field.code-workspace deleted file mode 100644 index 982f300..0000000 --- a/pub/code_field-master/code_field.code-workspace +++ /dev/null @@ -1,15 +0,0 @@ -{ - "folders": [ - { - "path": "." - } - ], - "settings": { - "dart.vmAdditionalArgs": [ - "--no-sound-null-safety" - ], - "dart.flutterRunAdditionalArgs": [ - "--no-sound-null-safety" - ] - } -} \ No newline at end of file diff --git a/pub/code_field-master/doc/images/android.png b/pub/code_field-master/doc/images/android.png deleted file mode 100644 index 49b6a2b..0000000 Binary files a/pub/code_field-master/doc/images/android.png and /dev/null differ diff --git a/pub/code_field-master/doc/images/example_0.png b/pub/code_field-master/doc/images/example_0.png deleted file mode 100644 index 5efeed6..0000000 Binary files a/pub/code_field-master/doc/images/example_0.png and /dev/null differ diff --git a/pub/code_field-master/doc/images/example_1.png b/pub/code_field-master/doc/images/example_1.png deleted file mode 100644 index 4bb1f10..0000000 Binary files a/pub/code_field-master/doc/images/example_1.png and /dev/null differ diff --git a/pub/code_field-master/doc/images/example_2.png b/pub/code_field-master/doc/images/example_2.png deleted file mode 100644 index 546123c..0000000 Binary files a/pub/code_field-master/doc/images/example_2.png and /dev/null differ diff --git a/pub/code_field-master/doc/images/example_3.png b/pub/code_field-master/doc/images/example_3.png deleted file mode 100644 index fd69854..0000000 Binary files a/pub/code_field-master/doc/images/example_3.png and /dev/null differ diff --git a/pub/code_field-master/doc/images/long_line.gif b/pub/code_field-master/doc/images/long_line.gif deleted file mode 100644 index b00829f..0000000 Binary files a/pub/code_field-master/doc/images/long_line.gif and /dev/null differ diff --git a/pub/code_field-master/doc/images/top.gif b/pub/code_field-master/doc/images/top.gif deleted file mode 100644 index dc6c55c..0000000 Binary files a/pub/code_field-master/doc/images/top.gif and /dev/null differ diff --git a/pub/code_field-master/doc/images/typing.gif b/pub/code_field-master/doc/images/typing.gif deleted file mode 100644 index febb113..0000000 Binary files a/pub/code_field-master/doc/images/typing.gif and /dev/null differ diff --git a/pub/code_field-master/example/.gitignore b/pub/code_field-master/example/.gitignore deleted file mode 100644 index 0fa6b67..0000000 --- a/pub/code_field-master/example/.gitignore +++ /dev/null @@ -1,46 +0,0 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp -.DS_Store -.atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws -.idea/ - -# The .vscode folder contains launch configuration and tasks you configure in -# VS Code which you may wish to be included in version control, so this line -# is commented out by default. -#.vscode/ - -# Flutter/Dart/Pub related -**/doc/api/ -**/ios/Flutter/.last_build_id -.dart_tool/ -.flutter-plugins -.flutter-plugins-dependencies -.packages -.pub-cache/ -.pub/ -/build/ - -# Web related -lib/generated_plugin_registrant.dart - -# Symbolication related -app.*.symbols - -# Obfuscation related -app.*.map.json - -# Android Studio will place build artifacts here -/android/app/debug -/android/app/profile -/android/app/release diff --git a/pub/code_field-master/example/.metadata b/pub/code_field-master/example/.metadata deleted file mode 100644 index 80206eb..0000000 --- a/pub/code_field-master/example/.metadata +++ /dev/null @@ -1,10 +0,0 @@ -# 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: c5a4b4029c0798f37c4a39b479d7cb75daa7b05c - channel: stable - -project_type: app diff --git a/pub/code_field-master/example/android/.gitignore b/pub/code_field-master/example/android/.gitignore deleted file mode 100644 index 0a741cb..0000000 --- a/pub/code_field-master/example/android/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -gradle-wrapper.jar -/.gradle -/captures/ -/gradlew -/gradlew.bat -/local.properties -GeneratedPluginRegistrant.java - -# Remember to never publicly share your keystore. -# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app -key.properties diff --git a/pub/code_field-master/example/android/app/build.gradle b/pub/code_field-master/example/android/app/build.gradle deleted file mode 100644 index 6ca2344..0000000 --- a/pub/code_field-master/example/android/app/build.gradle +++ /dev/null @@ -1,59 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -def flutterVersionCode = localProperties.getProperty('flutter.versionCode') -if (flutterVersionCode == null) { - flutterVersionCode = '1' -} - -def flutterVersionName = localProperties.getProperty('flutter.versionName') -if (flutterVersionName == null) { - flutterVersionName = '1.0' -} - -apply plugin: 'com.android.application' -apply plugin: 'kotlin-android' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 30 - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.example" - minSdkVersion 16 - targetSdkVersion 30 - versionCode flutterVersionCode.toInteger() - versionName flutterVersionName - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/pub/code_field-master/example/android/app/src/debug/AndroidManifest.xml b/pub/code_field-master/example/android/app/src/debug/AndroidManifest.xml deleted file mode 100644 index c208884..0000000 --- a/pub/code_field-master/example/android/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/pub/code_field-master/example/android/app/src/main/AndroidManifest.xml b/pub/code_field-master/example/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index 34dd77e..0000000 --- a/pub/code_field-master/example/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/pub/code_field-master/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/pub/code_field-master/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt deleted file mode 100644 index e793a00..0000000 --- a/pub/code_field-master/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.example - -import io.flutter.embedding.android.FlutterActivity - -class MainActivity: FlutterActivity() { -} diff --git a/pub/code_field-master/example/android/app/src/main/res/drawable-v21/launch_background.xml b/pub/code_field-master/example/android/app/src/main/res/drawable-v21/launch_background.xml deleted file mode 100644 index f74085f..0000000 --- a/pub/code_field-master/example/android/app/src/main/res/drawable-v21/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/pub/code_field-master/example/android/app/src/main/res/drawable/launch_background.xml b/pub/code_field-master/example/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f..0000000 --- a/pub/code_field-master/example/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/pub/code_field-master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/pub/code_field-master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4..0000000 Binary files a/pub/code_field-master/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and /dev/null differ diff --git a/pub/code_field-master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/pub/code_field-master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b7..0000000 Binary files a/pub/code_field-master/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and /dev/null differ diff --git a/pub/code_field-master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/pub/code_field-master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png deleted file mode 100644 index 09d4391..0000000 Binary files a/pub/code_field-master/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and /dev/null differ diff --git a/pub/code_field-master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/pub/code_field-master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d..0000000 Binary files a/pub/code_field-master/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and /dev/null differ diff --git a/pub/code_field-master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/pub/code_field-master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372e..0000000 Binary files a/pub/code_field-master/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and /dev/null differ diff --git a/pub/code_field-master/example/android/app/src/main/res/values-night/styles.xml b/pub/code_field-master/example/android/app/src/main/res/values-night/styles.xml deleted file mode 100644 index 449a9f9..0000000 --- a/pub/code_field-master/example/android/app/src/main/res/values-night/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/pub/code_field-master/example/android/app/src/main/res/values/styles.xml b/pub/code_field-master/example/android/app/src/main/res/values/styles.xml deleted file mode 100644 index d74aa35..0000000 --- a/pub/code_field-master/example/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - diff --git a/pub/code_field-master/example/android/app/src/profile/AndroidManifest.xml b/pub/code_field-master/example/android/app/src/profile/AndroidManifest.xml deleted file mode 100644 index c208884..0000000 --- a/pub/code_field-master/example/android/app/src/profile/AndroidManifest.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - diff --git a/pub/code_field-master/example/android/build.gradle b/pub/code_field-master/example/android/build.gradle deleted file mode 100644 index c505a86..0000000 --- a/pub/code_field-master/example/android/build.gradle +++ /dev/null @@ -1,31 +0,0 @@ -buildscript { - ext.kotlin_version = '1.3.50' - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/pub/code_field-master/example/android/gradle.properties b/pub/code_field-master/example/android/gradle.properties deleted file mode 100644 index 94adc3a..0000000 --- a/pub/code_field-master/example/android/gradle.properties +++ /dev/null @@ -1,3 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.useAndroidX=true -android.enableJetifier=true diff --git a/pub/code_field-master/example/android/gradle/wrapper/gradle-wrapper.properties b/pub/code_field-master/example/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index bc6a58a..0000000 --- a/pub/code_field-master/example/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 23 08:50:38 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/pub/code_field-master/example/android/settings.gradle b/pub/code_field-master/example/android/settings.gradle deleted file mode 100644 index 44e62bc..0000000 --- a/pub/code_field-master/example/android/settings.gradle +++ /dev/null @@ -1,11 +0,0 @@ -include ':app' - -def localPropertiesFile = new File(rootProject.projectDir, "local.properties") -def properties = new Properties() - -assert localPropertiesFile.exists() -localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } - -def flutterSdkPath = properties.getProperty("flutter.sdk") -assert flutterSdkPath != null, "flutter.sdk not set in local.properties" -apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Black.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Black.ttf deleted file mode 100644 index fe62ead..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Black.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-BlackItalic.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-BlackItalic.ttf deleted file mode 100644 index a412dd9..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-BlackItalic.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Bold.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Bold.ttf deleted file mode 100644 index c790e04..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Bold.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-BoldItalic.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-BoldItalic.ttf deleted file mode 100644 index 0878199..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-BoldItalic.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-ExtraLight.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-ExtraLight.ttf deleted file mode 100644 index ca7bce8..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-ExtraLight.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-ExtraLightItalic.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-ExtraLightItalic.ttf deleted file mode 100644 index c33f284..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-ExtraLightItalic.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Italic.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Italic.ttf deleted file mode 100644 index 91a2a44..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Italic.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Light.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Light.ttf deleted file mode 100644 index 7af27ce..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Light.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-LightItalic.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-LightItalic.ttf deleted file mode 100644 index 330c523..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-LightItalic.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Medium.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Medium.ttf deleted file mode 100644 index 6450399..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Medium.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-MediumItalic.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-MediumItalic.ttf deleted file mode 100644 index 50cd774..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-MediumItalic.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Regular.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Regular.ttf deleted file mode 100644 index 3563e73..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-Regular.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-SemiBold.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-SemiBold.ttf deleted file mode 100644 index 526be56..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-SemiBold.ttf and /dev/null differ diff --git a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-SemiBoldItalic.ttf b/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-SemiBoldItalic.ttf deleted file mode 100644 index 689c138..0000000 Binary files a/pub/code_field-master/example/assets/fonts/sourceCode/SourceCodePro-SemiBoldItalic.ttf and /dev/null differ diff --git a/pub/code_field-master/example/deploy.sh b/pub/code_field-master/example/deploy.sh deleted file mode 100644 index a7bd3cb..0000000 --- a/pub/code_field-master/example/deploy.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env sh -# package.json "deploy": "yarn build; push-dir --dir=dist --branch=gh-pages --cleanup" - -# abort on errors -set -e - -# build -flutter build web --release --no-sound-null-safety - -# navigate into the build output directory -cd build/web - -# Commit repo -git init -git add -A -git commit -m 'deploy' -git push -f git@github.com:BertrandBev/code_field.git master:gh-pages - -# Nav back -cd - \ No newline at end of file diff --git a/pub/code_field-master/example/ios/.gitignore b/pub/code_field-master/example/ios/.gitignore deleted file mode 100644 index e96ef60..0000000 --- a/pub/code_field-master/example/ios/.gitignore +++ /dev/null @@ -1,32 +0,0 @@ -*.mode1v3 -*.mode2v3 -*.moved-aside -*.pbxuser -*.perspectivev3 -**/*sync/ -.sconsign.dblite -.tags* -**/.vagrant/ -**/DerivedData/ -Icon? -**/Pods/ -**/.symlinks/ -profile -xcuserdata -**/.generated/ -Flutter/App.framework -Flutter/Flutter.framework -Flutter/Flutter.podspec -Flutter/Generated.xcconfig -Flutter/app.flx -Flutter/app.zip -Flutter/flutter_assets/ -Flutter/flutter_export_environment.sh -ServiceDefinitions.json -Runner/GeneratedPluginRegistrant.* - -# Exceptions to above rules. -!default.mode1v3 -!default.mode2v3 -!default.pbxuser -!default.perspectivev3 diff --git a/pub/code_field-master/example/ios/Flutter/AppFrameworkInfo.plist b/pub/code_field-master/example/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 9367d48..0000000 --- a/pub/code_field-master/example/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 8.0 - - diff --git a/pub/code_field-master/example/ios/Flutter/Debug.xcconfig b/pub/code_field-master/example/ios/Flutter/Debug.xcconfig deleted file mode 100644 index ec97fc6..0000000 --- a/pub/code_field-master/example/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" -#include "Generated.xcconfig" diff --git a/pub/code_field-master/example/ios/Flutter/Release.xcconfig b/pub/code_field-master/example/ios/Flutter/Release.xcconfig deleted file mode 100644 index c4855bf..0000000 --- a/pub/code_field-master/example/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1,2 +0,0 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" -#include "Generated.xcconfig" diff --git a/pub/code_field-master/example/ios/Podfile b/pub/code_field-master/example/ios/Podfile deleted file mode 100644 index 1e8c3c9..0000000 --- a/pub/code_field-master/example/ios/Podfile +++ /dev/null @@ -1,41 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '9.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def flutter_root - generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) - unless File.exist?(generated_xcode_build_settings_path) - raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" - end - - File.foreach(generated_xcode_build_settings_path) do |line| - matches = line.match(/FLUTTER_ROOT\=(.*)/) - return matches[1].strip if matches - end - raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" -end - -require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) - -flutter_ios_podfile_setup - -target 'Runner' do - use_frameworks! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - flutter_additional_ios_build_settings(target) - end -end diff --git a/pub/code_field-master/example/ios/Runner.xcodeproj/project.pbxproj b/pub/code_field-master/example/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index c6759a6..0000000 --- a/pub/code_field-master/example/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,471 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 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 */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, - 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, - ); - path = Runner; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 1020; - ORGANIZATIONNAME = ""; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - LastSwiftMigration = 1100; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 249021D3217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Profile; - }; - 249021D4217E4FDB00AE95B9 /* Profile */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Profile; - }; - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - ENABLE_BITCODE = NO; - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - PRODUCT_BUNDLE_IDENTIFIER = com.example.example; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; - SWIFT_VERSION = 5.0; - VERSIONING_SYSTEM = "apple-generic"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - 249021D3217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - 249021D4217E4FDB00AE95B9 /* Profile */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 919434a..0000000 --- a/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c..0000000 --- a/pub/code_field-master/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/pub/code_field-master/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/pub/code_field-master/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index a28140c..0000000 --- a/pub/code_field-master/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pub/code_field-master/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/pub/code_field-master/example/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a1..0000000 --- a/pub/code_field-master/example/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/pub/code_field-master/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/pub/code_field-master/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d9810..0000000 --- a/pub/code_field-master/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/pub/code_field-master/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/pub/code_field-master/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index f9b0d7c..0000000 --- a/pub/code_field-master/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,8 +0,0 @@ - - - - - PreviewsEnabled - - - diff --git a/pub/code_field-master/example/ios/Runner/AppDelegate.swift b/pub/code_field-master/example/ios/Runner/AppDelegate.swift deleted file mode 100644 index 70693e4..0000000 --- a/pub/code_field-master/example/ios/Runner/AppDelegate.swift +++ /dev/null @@ -1,13 +0,0 @@ -import UIKit -import Flutter - -@UIApplicationMain -@objc class AppDelegate: FlutterAppDelegate { - override func application( - _ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? - ) -> Bool { - GeneratedPluginRegistrant.register(with: self) - return super.application(application, didFinishLaunchingWithOptions: launchOptions) - } -} diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fa..0000000 --- a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "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/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index dc9ada4..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf0..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png deleted file mode 100644 index 2ccbfd9..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png deleted file mode 100644 index 4cde121..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png deleted file mode 100644 index dcdc230..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png deleted file mode 100644 index 2ccbfd9..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b86..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b86..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d16..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png deleted file mode 100644 index 6a84f41..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png deleted file mode 100644 index d0e1f58..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json deleted file mode 100644 index 0bedcf2..0000000 --- a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "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/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png deleted file mode 100644 index 9da19ea..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19ea..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19ea..0000000 Binary files a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png and /dev/null differ diff --git a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725..0000000 --- a/pub/code_field-master/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# 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/pub/code_field-master/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/pub/code_field-master/example/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c..0000000 --- a/pub/code_field-master/example/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pub/code_field-master/example/ios/Runner/Base.lproj/Main.storyboard b/pub/code_field-master/example/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c2851..0000000 --- a/pub/code_field-master/example/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pub/code_field-master/example/ios/Runner/Info.plist b/pub/code_field-master/example/ios/Runner/Info.plist deleted file mode 100644 index a060db6..0000000 --- a/pub/code_field-master/example/ios/Runner/Info.plist +++ /dev/null @@ -1,45 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - example - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/pub/code_field-master/example/ios/Runner/Runner-Bridging-Header.h b/pub/code_field-master/example/ios/Runner/Runner-Bridging-Header.h deleted file mode 100644 index 308a2a5..0000000 --- a/pub/code_field-master/example/ios/Runner/Runner-Bridging-Header.h +++ /dev/null @@ -1 +0,0 @@ -#import "GeneratedPluginRegistrant.h" diff --git a/pub/code_field-master/example/lib/code_snippets.dart b/pub/code_field-master/example/lib/code_snippets.dart deleted file mode 100644 index 68addfa..0000000 --- a/pub/code_field-master/example/lib/code_snippets.dart +++ /dev/null @@ -1,373 +0,0 @@ -// Copied from https://github.com/git-touch/highlight - -const CODE_SNIPPETS = { - '1c': - '#ЗагрузитьИзФайла ext_module.txt // директива 7.7\n#Если Клиент ИЛИ НаКлиенте Тогда // инструкции препроцессора\n &НаКлиентеНаСервереБезКонтекста // директивы компиляции\n Функция ТолстыйКлиентОбычноеПриложение(Знач Параметр1 = Неопределено, // комментарий\n Параметр2 = "", ПараметрN = 123.45, ПарамNN) Экспорт // еще комментарий\n Попытка\n Результат_Булевы_Значения = Новый Структура("П1, П2", Истина, Ложь, NULL, Неопределено);\n Перейти ~МеткаGOTO; // комментарий\n РезультатТаблицаДат = Новый ТаблицаЗначений;\n РезультатТаблицаДат.Колонки.Добавить("Колонка1", \n Новый ОписаниеТипов("Дата", , ,\n Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя));\n НС = РезультатТаблицаДат.Добавить(); НС["Колонка1"] = \'20170101120000\');\n Исключение\n ОписаниеОшибки = ОписаниеОшибки(); // встроенная функция\n Масс = Новый Массив; // встроенный тип\n Для Каждого Значение Из Масс Цикл\n Сообщить(Значение + Символы.ПС + "\n |продолжение строки"); // продолжение многострочной строки\n Продолжить; Прервать;\n КонецЦикла;\n СправочникСсылка = Справочники.Языки.НайтиПоНаименованию("ru"); // встроенные типы\n СправочникОбъект = СправочникСсылка.ПолучитьОбъект();\n ПеречислениеСсылка = Перечисления.ВидыМодификацииДанных.Изменен;\n ВызватьИсключение ОписаниеОшибки;\n КонецПопытки;\n ~МеткаGOTO: // еще комментарий\n ВД = ВидДвиженияБухгалтерии.Дебет;\n КонецФункции // ТолстыйКлиентОбычноеПриложение()\n#КонецЕсли', - 'abnf': - '; line comment\n\nruleset = [optional] *(group1 / group2 / SP) CRLF ; trailing comment\n\ngroup1 = alt1\ngroup1 =/ alt2\n\nalt1 = %x41-4D / %d78-90\n\nalt2 = %b00100001\n\ngroup2 = *1DIGIT / 2*HEXDIG / 3*4OCTET\n\noptional = hex-codes\n / literal\n / sensitive\n / insensitive\n\nhex-codes = %x68.65.6C.6C.6F\nliteral = "string literal"\nsensitive = %s"case-sensitive string"\ninsensitive = %i"case-insensitive string"\n', - 'accesslog': - '20.164.151.111 - - [20/Aug/2015:22:20:18 -0400] "GET /mywebpage/index.php HTTP/1.1" 403 772 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.220 Safari/535.1"\n', - 'actionscript': - 'package org.example.dummy {\n import org.dummy.*;\n\n /*define package inline interface*/\n public interface IFooBarzable {\n public function foo(... pairs):Array;\n }\n\n public class FooBar implements IFooBarzable {\n static private var cnt:uint = 0;\n private var bar:String;\n\n //constructor\n public function TestBar(bar:String):void {\n bar = bar;\n ++cnt;\n }\n\n public function foo(... pairs):Array {\n pairs.push(bar);\n return pairs;\n }\n }\n}', - 'ada': - 'package body Sqlite.Simple is\n\n Foo : int := int\'Size;\n Bar : int := long\'Size;\n\n Error_Message_C : chars_ptr := Sqlite_Errstr (Error);\n Error_Message : String := Null_Ignore_Value (Error_Message_C);\n begin\n\n Named : for Index in Foo..Bar loop\n Put ("Hi[]{}");\n end loop Named;\n\n Foo := Bar;\n end Message;\n\nend Sqlite.Simple;\n', - 'angelscript': - 'interface IInterface\n{\n void DoSomething();\n}\n\nnamespace MyApplication\n{\n /*\n * This ia a test class.\n */\n class SomeClass : IInterface\n {\n array m_arr;\n\n array m_children;\n array> m_subChildren; // Nested templates\n\n int m_thing;\n\n SomeClass()\n {\n // Add some integers\n m_arr.insertLast(1.0f);\n m_arr.insertLast(1.75f);\n m_arr.insertLast(3.14159f);\n uint x = 0x7fff0000;\n int y = 9001;\n }\n\n int get_Thing() property { return m_thing; }\n void set_Thing(int x) property { m_thing = x; }\n\n void DoSomething()\n {\n print("Something! " + \'stuff.\');\n for (uint i = 0; i < m_arr.length(); i++) {\n print(" " + i + ": " + m_arr[i]);\n }\n }\n\n protected void SomeProtectedFunction()\n {\n try {\n DoSomething();\n } catch {\n print("Exception while doing something!");\n }\n }\n }\n}\n\nvoid Main()\n{\n SomeClass@ c = SomeClass();\n c.DoSomething();\n}\n', - 'apache': - '# rewrite`s rules for wordpress pretty url\nLoadModule rewrite_module modules/mod_rewrite.so\nRewriteCond %{REQUEST_FILENAME} !-f\nRewriteCond %{REQUEST_FILENAME} !-d\nRewriteRule . index.php [NC,L]\n\nExpiresActive On\nExpiresByType application/x-javascript "access plus 1 days"\n\nOrder Deny,Allow\nAllow from All\n\n\n RewriteMap map txt:map.txt\n RewriteMap lower int:tolower\n RewriteCond %{REQUEST_URI} ^/([^/.]+)\\.html\$ [NC]\n RewriteCond \${map:\${lower:%1}|NOT_FOUND} !NOT_FOUND\n RewriteRule .? /index.php?q=\${map:\${lower:%1}} [NC,L]\n\n', - 'applescript': - 'repeat 5 times\n if foo is greater than bar then\n display dialog "Hello there"\n else\n beep\n end if\nend repeat\n\n(* comment (*nested comment*) *)\non do_something(s, y)\n return {s + pi, y mod 4}\nend do_something\n\ndo shell script "/bin/echo \'hello\'"\n', - 'arcade': - '/* Highlight.js est for Arcade */\nfunction testGeometry(element, point) {\n if (point.y != -1)\n return point;\n for (var i = 0 / 2; i < element.length; i++) {\n if (checkCondition(\$map.element[i]) === Infinity) {\n return DistanceGeodetic(element[i]);\n }\n }\n return element;\n}\nvar filePath = "literal " + TextFormatting.BackSlash + TextFormatting.SingleQuote + ".ext"\nvar d = Dictionary("field1", 1, "field2",2);\nreturn FeatureSet(\$map, ["POPULATION", "ELECTION-DATA"]);\n', - 'arduino': - '/*\n Blink\n Turns on an LED on for one second, then off for one second, repeatedly.\n \n This example code is in the public domain.\n */\n \n// Pin 13 has an LED connected on most Arduino boards.\n// give it a name:\nint led = 13;\n\n// the setup routine runs once when you press reset:\nvoid setup() {\n // initialize the digital pin as an output.\n pinMode(led, OUTPUT); \n}\n\n// the loop routine runs over and over again forever:\nvoid loop() {\n digitalWrite(led, HIGH); // turn the LED on (HIGH is the voltage level)\n delay(1000); // wait for a second\n digitalWrite(led, LOW); // turn the LED off by making the voltage LOW\n delay(1000); // wait for a second\n}', - 'armasm': - '.text\n\n.global connect\nconnect:\n mov r3, #2 ; s->sin_family = AF_INET\n strh r3, [sp]\n ldr r3, =server_port ; s->sin_port = server_port\n ldr r3, [r3]\n strh r3, [sp, #2]\n ldr r3, =server_addr ; s->sin_addr = server_addr\n ldr r3, [r3]\n str r3, [sp, #4]\n mov r3, #0 ; bzero(&s->sin_zero)\n str r3, [sp, #8]\n str r3, [sp, #12]\n mov r1, sp ; const struct sockaddr *addr = sp\n\n ldr r7, =connect_call\n ldr r7, [r7]\n swi #0\n\n add sp, sp, #16\n pop {r0} ; pop sockfd\n\n pop {r7}\n pop {fp, ip, lr}\n mov sp, ip\n bx lr\n\n.data\nsocket_call: .long 281\nconnect_call: .long 283\n\n/* all addresses are network byte-order (big-endian) */\nserver_addr: .long 0x0100007f ; localhost\nserver_port: .hword 0x0b1a\n', - 'asciidoc': - 'Hello, World!\n============\nAuthor Name, \n\nyou can write text http://example.com[with links], optionally\nusing an explicit link:http://example.com[link prefix].\n\n* single quotes around a phrase place \'emphasis\'\n** alternatively, you can put underlines around a phrase to add _emphasis_\n* astericks around a phrase make the text *bold*\n* pluses around a phrase make it +monospaced+\n* `smart\' quotes using a leading backtick and trailing single quote\n** use two of each for double ``smart\'\' quotes\n\n- escape characters are supported\n- you can escape a quote inside emphasized text like \'here\\\'s johnny!\'\n\nterm:: definition\n another term:: another definition\n\n// this is just a comment\n\nLet\'s make a break.\n\n\'\'\'\n\n////\nwe\'ll be right with you\n\nafter this brief interruption.\n////\n\n== We\'re back!\n\nWant to see a image::images/tiger.png[Tiger]?\n\n.Nested highlighting\n++++\n\n++++\n\n____\nasciidoc is so powerful.\n____\n\nanother quote:\n\n[quote, Sir Arthur Conan Doyle, The Adventures of Sherlock Holmes]\n____\nWhen you have eliminated all which is impossible, then whatever remains, however improbable, must be the truth.\n____\n\nGetting Literal\n---------------\n\n want to get literal? prefix a line with a space.\n\n....\nI\'ll join that party, too.\n....\n\n. one thing (yeah!)\n. two thing `i can write code`, and `more` wipee!\n\nNOTE: AsciiDoc is quite cool, you should try it.', - 'aspectj': - 'package com.aspectj.syntax;\nimport org.aspectj.lang.annotation.AdviceName;\n\nprivileged public aspect LoggingAspect percflowbelow(ajia.services.*){\n private pointcut getResult() : call(* *(..) throws SQLException) && args(Account, .., int);\n @AdviceName("CheckValidEmail")\n before (Customer hu) : getResult(hu){ \n System.out.println("Your mail address is valid!");\n }\n Object around() throws InsufficientBalanceException: getResult() && call(Customer.new(String,String,int,int,int)){\n return proceed();\n }\n public Cache getCache() {\n return this.cache;\n }\n pointcut beanPropertyChange(BeanSupport bean, Object newValue): execution(void BeanSupport+.set*(*)) && args(newValue) && this(bean);\n declare parents: banking.entities.* implements BeanSupport;\n declare warning : call(void TestSoftening.perform()): "Please ensure you are not calling this from an AWT thread";\n private String Identifiable.id;\n public void Identifiable.setId(String id) {\n this.id = id;\n }\n}', - 'autohotkey': - '; hotkeys and hotstrings\n#a::WinSet, AlwaysOnTop, Toggle, A\n#Space::\n MsgBox, Percent sign (`%) need to be escaped.\n Run "C:\\Program Files\\some\\program.exe"\n Gosub, label1\nreturn\n::btw::by the way\n; volume\n#Numpad8::Send {Volume_Up}\n#Numpad5::Send {Volume_Mute}\n#Numpad2::Send {Volume_Down}\n\nlabel1:\n if (Clipboard = "")\n {\n MsgBox, , Clipboard, Empty!\n }\n else\n {\n StringReplace, temp, Clipboard, old, new, All\n MsgBox, , Clipboard, %temp%\n }\nreturn\n', - 'autoit': - '#NoTrayIcon\n#AutoIt3Wrapper_Run_Tidy=Y\n#include \n\n_Singleton(@ScriptName) ; Allow only one instance\nexample(0, 10)\n\nFunc example(\$min, \$max)\n For \$i = \$min To \$max\n If Mod(\$i, 2) == 0 Then\n MsgBox(64, "Message", \$i & \' is even number!\')\n Else\n MsgBox(64, "Message", \$i & \' is odd number!\')\n EndIf\n Next\nEndFunc ;==>example', - 'avrasm': - ';* Title: Block Copy Routines\n;* Version: 1.1\n\n.include "8515def.inc"\n\n rjmp RESET ;reset handle\n\n.def flashsize=r16 ;size of block to be copied\n\nflash2ram:\n lpm ;get constant\n st Y+,r0 ;store in SRAM and increment Y-pointer\n adiw ZL,1 ;increment Z-pointer\n dec flashsize\n brne flash2ram ;if not end of table, loop more\n ret\n\n.def ramtemp =r1 ;temporary storage register\n.def ramsize =r16 ;size of block to be copied\n', - 'awk': - 'BEGIN {\n POPService = "/inet/tcp/0/emailhost/pop3"\n RS = ORS = "\\r\\n"\n print "user name" |& POPService\n POPService |& getline\n print "pass password" |& POPService\n POPService |& getline\n print "retr 1" |& POPService\n POPService |& getline\n if (\$1 != "+OK") exit\n print "quit" |& POPService\n RS = "\\r\\n\\\\.\\r\\n"\n POPService |& getline\n print \$0\n close(POPService)\n}\n', - 'axapta': - 'class ExchRateLoadBatch extends RunBaseBatch {\n ExchRateLoad rbc;\n container currencies;\n boolean actual;\n boolean overwrite;\n date beg;\n date end;\n\n #define.CurrentVersion(5)\n\n #localmacro.CurrentList\n currencies,\n actual,\n beg,\n end\n #endmacro\n}\n\npublic boolean unpack(container packedClass) {\n container base;\n boolean ret;\n Integer version = runbase::getVersion(packedClass);\n\n switch (version) {\n case #CurrentVersion:\n [version, #CurrentList] = packedClass;\n return true;\n default:\n return false;\n }\n return ret;\n}\n', - 'bash': - '#!/bin/bash\n\n###### CONFIG\nACCEPTED_HOSTS="/root/.hag_accepted.conf"\nBE_VERBOSE=false\n\nif [ "\$UID" -ne 0 ]\nthen\n echo "Superuser rights required"\n exit 2\nfi\n\ngenApacheConf(){\n echo -e "# Host \${HOME_DIR}\$1/\$2 :"\n}\n\necho \'"quoted"\' | tr -d \\" > text.txt\n', - 'basic': - '10 CLS\n20 FOR I = 0 TO 15\n22 FOR J = 0 TO 7\n30 COLOR I,J\n40 PRINT " ** ";\n45 NEXT J\n46 COLOR I,0\n47 GOSUB 100\n48 PRINT\n50 NEXT I\n60 COLOR 15,0\n99 END\n100 FOR T = 65 TO 90\n101 PRINT CHR\$(T);\n102 NEXT T\n103 RETURN\n200 REM Data types test\n201 TOTAL# = 3.30# \'Double precision variable\n202 BALANCE! = 3! \'Single precision variable\n203 B2! = 12e5 \'120000\n204 ITEMS% = 10 \'Integer variable\n205 HEXTEST = &H12DB \'Hex value\n', - 'bnf': - ' ::= | \n ::= "<" ">" "::=" \n ::= " " | ""\n ::= | "|" \n ::= | \n ::= | \n ::= | "<" ">"\n ::= \'"\' \'"\' | "\'" "\'"\n', - 'brainfuck': - '++++++++++\n[ 3*10 and 10*10\n ->+++>++++++++++<<\n]>>\n[ filling cells\n ->++>>++>++>+>++>>++>++>++>++>++>++>++>++>++>++>++[>\n]<\n+++++++++<<\n[ rough codes correction loop\n ->>>+>+>+>+++>+>+>+>+>+>+>+>+>+>+>+>+>+>+[<]<\n]\nmore accurate сodes correction\n>>>++>\n-->+++++++>------>++++++>++>+++++++++>++++++++++>++++++++>--->++++++++++>------>++++++>\n++>+++++++++++>++++++++++++>------>+++\nrewind and output\n[<]>[.>]\n', - 'cal': - 'OBJECT Codeunit 11 Gen. Jnl.-Check Line\n{\n OBJECT-PROPERTIES\n {\n Date=09-09-14;\n Time=12:00:00;\n Version List=NAVW18.00;\n }\n PROPERTIES\n {\n TableNo=81;\n Permissions=TableData 252=rimd;\n OnRun=BEGIN\n GLSetup.GET;\n RunCheck(Rec);\n END;\n\n }\n CODE\n {\n VAR\n Text000@1000 : TextConst \'ENU=can only be a closing date for G/L entries\';\n Text001@1001 : TextConst \'ENU=is not within your range of allowed posting dates\';\n\n PROCEDURE ErrorIfPositiveAmt@2(GenJnlLine@1000 : Record 81);\n BEGIN\n IF GenJnlLine.Amount > 0 THEN\n GenJnlLine.FIELDERROR(Amount,Text008);\n END;\n\n LOCAL PROCEDURE CheckGenJnlLineDocType@7(GenJnlLine@1001 : Record 81);\n }\n}\n', - 'capnproto': - '@0xdbb9ad1f14bf0b36; # unique file ID, generated by `capnp id`\n\nstruct Person {\n name @0 :Text;\n birthdate @3 :Date;\n\n email @1 :Text;\n phones @2 :List(PhoneNumber);\n\n struct PhoneNumber {\n number @0 :Text;\n type @1 :Type;\n\n enum Type {\n mobile @0;\n home @1;\n work @2;\n }\n }\n}\n\nstruct Date {\n year @0 :Int16;\n month @1 :UInt8;\n day @2 :UInt8;\n flags @3 :List(Bool) = [ true, false, false, true ];\n}\n\ninterface Node {\n isDirectory @0 () -> (result :Bool);\n}\n\ninterface Directory extends(Node) {\n list @0 () -> (list: List(Entry));\n struct Entry {\n name @0 :Text;\n node @1 :Node;\n }\n\n create @1 (name :Text) -> (file :File);\n mkdir @2 (name :Text) -> (directory :Directory)\n open @3 (name :Text) -> (node :Node);\n delete @4 (name :Text);\n link @5 (name :Text, node :Node);\n}\n\ninterface File extends(Node) {\n size @0 () -> (size: UInt64);\n read @1 (startAt :UInt64 = 0, amount :UInt64 = 0xffffffffffffffff)\n -> (data: Data);\n # Default params = read entire file.\n\n write @2 (startAt :UInt64, data :Data);\n truncate @3 (size :UInt64);\n}', - 'ceylon': - 'shared void run() {\n print("Hello, `` process.arguments.first else "World" ``!");\n}\nclass Counter(count=0) {\n variable Integer count;\n shared Integer currentValue => count;\n shared void increment() => count++;\n}\n', - 'clean': - 'module fsieve\n\nimport StdClass; // RWS\nimport StdInt, StdReal\n\nNrOfPrimes :== 3000\n\nprimes :: [Int]\nprimes = pr where pr = [5 : sieve 7 4 pr]\n\nsieve :: Int !Int [Int] -> [Int]\nsieve g i prs\n| isPrime prs g (toInt (sqrt (toReal g))) = [g : sieve` g i prs]\n| otherwise = sieve (g + i) (6 - i) prs\n\nsieve` :: Int Int [Int] -> [Int]\nsieve` g i prs = sieve (g + i) (6 - i) prs\n\nisPrime :: [Int] !Int Int -> Bool\nisPrime [f:r] pr bd\n| f>bd = True\n| pr rem f==0 = False\n| otherwise = isPrime r pr bd\n\nselect :: [x] Int -> x\nselect [f:r] 1 = f\nselect [f:r] n = select r (n - 1)\n\nStart :: Int\nStart = select [2, 3 : primes] NrOfPrimes\n', - 'clojure': - '(def ^:dynamic chunk-size 17)\n\n(defn next-chunk [rdr]\n (let [buf (char-array chunk-size)\n s (.read rdr buf)]\n (when (pos? s)\n (java.nio.CharBuffer/wrap buf 0 s))))\n\n(defn chunk-seq [rdr]\n (when-let [chunk (next-chunk rdr)]\n (cons chunk (lazy-seq (chunk-seq rdr)))))\n', - 'clojure-repl': - 'user=> (defn f [x y]\n #_=> (+ x y))\n#\'user/f\nuser=> (f 5 7)\n12\nuser=> nil\nnil\n', - 'cmake': - 'cmake_minimum_required(VERSION 2.8.8)\nproject(cmake_example)\n\n# Show message on Linux platform\nif (\${CMAKE_SYSTEM_NAME} MATCHES Linux)\n message("Good choice, bro!")\nendif()\n\n# Tell CMake to run moc when necessary:\nset(CMAKE_AUTOMOC ON)\n# As moc files are generated in the binary dir,\n# tell CMake to always look for includes there:\nset(CMAKE_INCLUDE_CURRENT_DIR ON)\n\n# Widgets finds its own dependencies.\nfind_package(Qt5Widgets REQUIRED)\n\nadd_executable(myproject main.cpp mainwindow.cpp)\nqt5_use_modules(myproject Widgets)\n', - 'coffeescript': - 'grade = (student, period=(if b? then 7 else 6)) ->\n if student.excellentWork\n "A+"\n else if student.okayStuff\n if student.triedHard then "B" else "B-"\n else\n "C"\n\nclass Animal extends Being\n constructor: (@name) ->\n\n move: (meters) ->\n alert @name + " moved #{meters}m."\n', - 'coq': - 'Inductive seq : nat -> Set :=\n| niln : seq 0\n| consn : forall n : nat, nat -> seq n -> seq (S n).\n\nFixpoint length (n : nat) (s : seq n) {struct s} : nat :=\n match s with\n | niln => 0\n | consn i _ s\' => S (length i s\')\n end.\n\nTheorem length_corr : forall (n : nat) (s : seq n), length n s = n.\nProof.\n intros n s.\n\n (* reasoning by induction over s. Then, we have two new goals\n corresponding on the case analysis about s (either it is\n niln or some consn *)\n induction s.\n\n (* We are in the case where s is void. We can reduce the\n term: length 0 niln *)\n simpl.\n\n (* We obtain the goal 0 = 0. *)\n trivial.\n\n (* now, we treat the case s = consn n e s with induction\n hypothesis IHs *)\n simpl.\n\n (* The induction hypothesis has type length n s = n.\n So we can use it to perform some rewriting in the goal: *)\n rewrite IHs.\n\n (* Now the goal is the trivial equality: S n = S n *)\n trivial.\n\n (* Now all sub cases are closed, we perform the ultimate\n step: typing the term built using tactics and save it as\n a witness of the theorem. *)\nQed.\n', - 'cos': - '#dim test as %Library.Integer\nSET test = 123.099\nset ^global = %request.Content\nWrite "Current date """, \$ztimestamp, """, result: ", test + ^global = 125.099\ndo ##class(Cinema.Utils).AddShow("test") // class method call\ndo ##super() ; another one-line comment\nd:(^global = 2) ..thisClassMethod(1, 2, "test")\n/*\n * Sub-languages support:\n */\n&sql( SELECT * FROM Cinema.Film WHERE Length > 2 )\n&js\n&html<\n\n \nTest\n>\n\nquit \$\$\$OK\n', - 'cpp': - '#include \n\nint main(int argc, char *argv[]) {\n\n /* An annoying "Hello World" example */\n for (auto i = 0; i < 0xFFFF; i++)\n cout << "Hello, World!" << endl;\n\n char c = \'\\n\';\n unordered_map > m;\n m["key"] = "\\\\\\\\"; // this is an error\n\n return -2e3 + 12l;\n}\n', - 'crmsh': - 'node webui\nnode 168633611: node1\nrsc_template web-server apache \\\n params port=8000 \\\n op monitor interval=10s\n# Never use this STONITH agent in production!\nprimitive development-stonith stonith:null \\\n params hostlist="webui node1 node2 node3"\nprimitive proxy systemd:haproxy \\\n op monitor interval=10s\nprimitive proxy-vip IPaddr2 \\\n params ip=10.13.37.20\nprimitive srv1 @web-server\nprimitive srv2 @web-server\nprimitive test1 Dummy\nprimitive test2 IPaddr2 \\\n params ip=10.13.37.99\nprimitive vip1 IPaddr2 \\\n params ip=10.13.37.21 \\\n op monitor interval=20s\nprimitive vip2 IPaddr2 \\\n params ip=10.13.37.22 \\\n op monitor interval=20s\ngroup g-proxy proxy-vip proxy\ngroup g-serv1 vip1 srv1\ngroup g-serv2 vip2 srv2\n# Never put the two web servers on the same node\ncolocation co-serv -inf: g-serv1 g-serv2\n# Never put any web server or haproxy on webui\nlocation l-avoid-webui { g-proxy g-serv1 g-serv2 } -inf: webui\n# Prever to spread groups across nodes\nlocation l-proxy g-proxy 200: node1\nlocation l-serv1 g-serv1 200: node2\nlocation l-serv2 g-serv2 200: node3\nproperty cib-bootstrap-options: \\\n stonith-enabled=true \\\n no-quorum-policy=ignore \\\n placement-strategy=balanced \\\n have-watchdog=false \\\n dc-version="1.1.13-1.1.13+git20150827.e8888b9" \\\n cluster-infrastructure=corosync \\\n cluster-name=hacluster\nrsc_defaults rsc-options: \\\n resource-stickiness=1 \\\n migration-threshold=3\nop_defaults op-options: \\\n timeout=600 \\\n record-pending=true\n', - 'crystal': - 'class Person\n def initialize(@name : String)\n end\n\n def greet\n puts "Hi, I\'m #{@name}"\n end\nend\n\nclass Employee < Person\nend\n\nemployee = Employee.new "John"\nemployee.greet # => "Hi, I\'m John"\nemployee.is_a?(Person) # => true\n\n@[Link("m")]\nlib C\n # In C: double cos(double x)\n fun cos(value : Float64) : Float64\nend\n\nC.cos(1.5_f64) # => 0.0707372\n\ns = uninitialized String\ns = <<-\'STR\'\n\\hello\\world\n\\hello\\world\nSTR\n', - 'cs': - 'using System.IO.Compression;\n\n#pragma warning disable 414, 3021\n\nnamespace MyApplication\n{\n [Obsolete("...")]\n class Program : IInterface\n {\n public static List JustDoIt(int count)\n {\n Console.WriteLine(\$"Hello {Name}!");\n return new List(new int[] { 1, 2, 3 })\n }\n }\n}\n', - 'csp': - 'Content-Security-Policy:\n default-src \'self\';\n style-src \'self\' css.example.com;\n img-src *.example.com;\n script-src \'unsafe-eval\' \'self\' js.example.com \'nonce-Nc3n83cnSAd3wc3Sasdfn939hc3\'\n', - 'css': - '@font-face {\n font-family: Chunkfive; src: url(\'Chunkfive.otf\');\n}\n\nbody, .usertext {\n color: #F0F0F0; background: #600;\n font-family: Chunkfive, sans;\n --heading-1: 30px/32px Helvetica, sans-serif;\n}\n\n@import url(print.css);\n@media print {\n a[href^=http]::after {\n content: attr(href)\n }\n}\n', - 'd': - '#!/usr/bin/rdmd\n// Computes average line length for standard input.\nimport std.stdio;\n\n/+\n this is a /+ nesting +/ comment\n+/\n\nenum COMPILED_ON = __TIMESTAMP__; // special token\n\nenum character = \'©\';\nenum copy_valid = \'©\';\nenum backslash_escaped = \'\\\\\';\n\n// string literals\nenum str = `hello "world"!`;\nenum multiline = r"lorem\nipsum\ndolor"; // wysiwyg string, no escapes here allowed\nenum multiline2 = "sit\namet\n\\"adipiscing\\"\nelit.";\nenum hex = x"66 6f 6f"; // same as "foo"\n\n#line 5\n\n// float literals\nenum f = [3.14f, .1, 1., 1e100, 0xc0de.01p+100];\n\nstatic if (something == true) {\n import std.algorithm;\n}\n\nvoid main() pure nothrow @safe {\n ulong lines = 0;\n double sumLength = 0;\n foreach (line; stdin.byLine()) {\n ++lines;\n sumLength += line.length;\n }\n writeln("Average line length: ",\n lines ? sumLength / lines : 0);\n}\n', - 'dart': - 'library app;\nimport \'dart:html\';\n\npart \'app2.dart\';\n\n/**\n * Class description and [link](http://dartlang.org/).\n */\n@Awesome(\'it works!\')\nclass SomeClass extends BaseClass implements Comparable {\n factory SomeClass(num param);\n SomeClass._internal(int q) : super() {\n assert(q != 1);\n double z = 0.0;\n }\n\n /// **Sum** function\n int sum(int a, int b) => a + b;\n\n ElementList els() => querySelectorAll(\'.dart\');\n}\n\nString str = \' (\${\'parameter\' + \'zxc\'})\';\nString str = " (\${true ? 2 + 2 / 2 : null})";\nString str = " (\$variable)";\nString str = r\'\\nraw\\\';\nString str = r"\\nraw\\";\nvar str = \'\'\'\nSomething \${2+3}\n\'\'\';\nvar str = r"""\nSomething \${2+3}\n""";\n\ncheckVersion() async {\n var version = await lookUpVersion();\n}\n', - 'delphi': - 'TList = Class(TObject)\nPrivate\n Some: String;\nPublic\n Procedure Inside; // Suxx\nEnd;{TList}\n\nProcedure CopyFile(InFileName, var OutFileName: String);\nConst\n BufSize = 4096; (* Huh? *)\nVar\n InFile, OutFile: TStream;\n Buffer: Array[1..BufSize] Of Byte;\n ReadBufSize: Integer;\nBegin\n InFile := Nil;\n OutFile := Nil;\n Try\n InFile := TFileStream.Create(InFileName, fmOpenRead);\n OutFile := TFileStream.Create(OutFileName, fmCreate);\n Repeat\n ReadBufSize := InFile.Read(Buffer, BufSize);\n OutFile.Write(Buffer, ReadBufSize);\n Until ReadBufSize<>BufSize;\n Log(\'File \'\'\' + InFileName + \'\'\' copied\'#13#10);\n Finally\n InFile.Free;\n OutFile.Free;\n End;{Try}\nEnd;{CopyFile}\n', - 'diff': - 'Index: languages/ini.js\n===================================================================\n--- languages/ini.js (revision 199)\n+++ languages/ini.js (revision 200)\n@@ -1,8 +1,7 @@\n hljs.LANGUAGES.ini =\n {\n case_insensitive: true,\n- defaultMode:\n- {\n+ defaultMode: {\n contains: [\'comment\', \'title\', \'setting\'],\n illegal: \'[^\\\\s]\'\n },\n\n*** /path/to/original timestamp\n--- /path/to/new timestamp\n***************\n*** 1,3 ****\n--- 1,9 ----\n+ This is an important\n+ notice! It should\n+ therefore be located at\n+ the beginning of this\n+ document!\n\n! compress the size of the\n! changes.\n\n It is important to spell\n', - 'django': - '{% if articles|length %}\n{% for article in articles %}\n\n{% custom %}\n\n{# Striped table #}\n\n {{ article|default:"Hi... " }}\n \n Published on {{ article.date }}\n \n\n\n{% endfor %}\n{% endif %}\n', - 'dns': - '\$ORIGIN example.com. ; designates the start of this zone file in the namespace\n\$TTL 1h ; default expiration time of all resource records without their own TTL value\nexample.com. IN SOA ns.example.com. username.example.com. ( 2007120710 1d 2h 4w 1h )\nexample.com. IN NS ns ; ns.example.com is a nameserver for example.com\nexample.com. IN NS ns.somewhere.example. ; ns.somewhere.example is a backup nameserver for example.com\nexample.com. IN MX 10 mail.example.com. ; mail.example.com is the mailserver for example.com\n@ IN MX 20 mail2.example.com. ; equivalent to above line, "@" represents zone origin\n@ IN MX 50 mail3 ; equivalent to above line, but using a relative host name\nexample.com. IN A 192.0.2.1 ; IPv4 address for example.com\n IN AAAA 2001:db8:10::1 ; IPv6 address for example.com\nns IN A 192.0.2.2 ; IPv4 address for ns.example.com\n IN AAAA 2001:db8:10::2 ; IPv6 address for ns.example.com\nwww IN CNAME example.com. ; www.example.com is an alias for example.com\nwwwtest IN CNAME www ; wwwtest.example.com is another alias for www.example.com\nmail IN A 192.0.2.3 ; IPv4 address for mail.example.com\nmail2 IN A 192.0.2.4 ; IPv4 address for mail2.example.com\nmail3 IN A 192.0.2.5 ; IPv4 address for mail3.example.com\n', - 'dockerfile': - '# Example instructions from https://docs.docker.com/reference/builder/\nFROM ubuntu:14.04\n\nMAINTAINER example@example.com\n\nENV foo /bar\nWORKDIR \${foo} # WORKDIR /bar\nADD . \$foo # ADD . /bar\nCOPY \\\$foo /quux # COPY \$foo /quux\nARG VAR=FOO\n\nRUN apt-get update && apt-get install -y software-properties-common\\\n zsh curl wget git htop\\\n unzip vim telnet\nRUN ["/bin/bash", "-c", "echo hello \${USER}"]\n\nCMD ["executable","param1","param2"]\nCMD command param1 param2\n\nEXPOSE 1337\n\nENV myName="John Doe" myDog=Rex\\ The\\ Dog \\\n myCat=fluffy\n\nENV myName John Doe\nENV myDog Rex The Dog\nENV myCat fluffy\n\nADD hom* /mydir/ # adds all files starting with "hom"\nADD hom?.txt /mydir/ # ? is replaced with any single character\n\nCOPY hom* /mydir/ # adds all files starting with "hom"\nCOPY hom?.txt /mydir/ # ? is replaced with any single character\nCOPY --from=foo / .\n\nENTRYPOINT ["executable", "param1", "param2"]\nENTRYPOINT command param1 param2\n\nVOLUME ["/data"]\n\nUSER daemon\n\nLABEL com.example.label-with-value="foo"\nLABEL version="1.0"\nLABEL description="This text illustrates \\\nthat label-values can span multiple lines."\n\nWORKDIR /path/to/workdir\n\nONBUILD ADD . /app/src\n\nSTOPSIGNAL SIGKILL\n\nHEALTHCHECK --retries=3 cat /health\n\nSHELL ["/bin/bash", "-c"]\n', - 'dos': - 'cd \\\ncopy a b\nping 192.168.0.1\n@rem ping 192.168.0.1\nnet stop sharedaccess\ndel %tmp% /f /s /q\ndel %temp% /f /s /q\nipconfig /flushdns\ntaskkill /F /IM JAVA.EXE /T\n\ncd Photoshop/Adobe Photoshop CS3/AMT/\nif exist application.sif (\n ren application.sif _application.sif\n) else (\n ren _application.sif application.sif\n)\n\ntaskkill /F /IM proquota.exe /T\n\nsfc /SCANNOW\n\nset path = test\n\nxcopy %1\\*.* %2\n', - 'dsconfig': - '# Create client connection policies\ndsconfig create-client-connection-policy \\\n --policy-name "Restrictive Client Connection Policy" \\\n --set "description:Restrictive Client Connection Policy" \\\n --set enabled:true --set evaluation-order-index:1000 \\\n --set "connection-criteria:User.0 Connection Criteria" \\\n --set maximum-concurrent-connections:2 \\\n --set "maximum-connection-duration:1 s" \\\n --set "maximum-idle-connection-duration:1 s" \\\n --set maximum-operation-count-per-connection:1000\ncreate-client-connection-policy \\\n --policy-name "Another Client Connection Policy" \\\n --set enabled:true --set evaluation-order-index:100 \\\n --set \'connection-criteria:User.1 Connection Criteria\' \\\n --reset maximum-concurrent-connections\n# Configure global ACIs\ndsconfig set-access-control-handler-prop \\\n --add global-aci:\'(target="ldap:///cn=config")(targetattr="*")(version 3.0; acl "Allow access to the config tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)\' \\\n --add global-aci:\'(target="ldap:///cn=monitor")(targetattr="*")(version 3.0; acl "Allow access to the monitor tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)\' \\\n --remove global-aci:\'(target="ldap:///cn=alerts")(targetattr="*")(version 3.0; acl "Allow access to the alerts tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)\'\n# Delete error logger\ndsconfig delete-log-publisher --publisher-name "File-Based Error Logger"\n', - 'dts': - '/*\n * Copyright (C) 2011 - 2014 Xilinx\n *\n * This software is licensed under the terms of the GNU General Public\n * License version 2, as published by the Free Software Foundation, and\n * may be copied, distributed, and modified under those terms.\n *\n * This program is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n */\n/include/ "skeleton.dtsi"\n\n/ {\n compatible = "xlnx,zynq-7000";\n\n pmu {\n compatible = "arm,cortex-a9-pmu";\n interrupts = <0 5 4>, <0 6 4>;\n interrupt-parent = <&intc>;\n reg = < 0xf8891000 0x1000 0xf8893000 0x1000 >;\n };\n\n regulator_vccpint: fixedregulator@0 {\n compatible = "regulator-fixed";\n regulator-name = "VCCPINT";\n regulator-min-microvolt = <1000000>;\n regulator-max-microvolt = <1000000>;\n regulator-boot-on;\n regulator-always-on;\n };\n\n amba: amba {\n compatible = "simple-bus";\n #address-cells = <1>;\n #size-cells = <1>;\n interrupt-parent = <&intc>;\n ranges;\n\n adc: adc@f8007100 {\n compatible = "xlnx,zynq-xadc-1.00.a";\n reg = <0xf8007100 0x20>;\n interrupts = <0 7 4>;\n interrupt-parent = <&intc>;\n clocks = <&clkc 12>;\n };\n\n i2c0: i2c@e0004000 {\n compatible = "cdns,i2c-r1p10";\n status = "disabled";\n clocks = <&clkc 38>;\n interrupt-parent = <&intc>;\n interrupts = <0 25 4>;\n reg = <0xe0004000 0x1000>;\n #address-cells = <1>;\n #size-cells = <0>;\n };\n\n L2: cache-controller@f8f02000 {\n compatible = "arm,pl310-cache";\n reg = <0xF8F02000 0x1000>;\n interrupts = <0 2 4>;\n arm,data-latency = <3 2 2>;\n arm,tag-latency = <2 2 2>;\n cache-unified;\n cache-level = <2>;\n };\n\n };\n};\n', - 'dust': - '

Hours

\n\n
    \n {#users}\n
  • {firstName}
  • {~n}\n {/users}\n
\n', - 'ebnf': - '(* line comment *)\n\nrule = [optional] , symbol , { letters } , ( digit | symbol ) ;\n\noptional = ? something unnecessary ? ; (* trailing comment *)\n\nsymbol = \'!\' | \'@\' | \'#\' | \'\$\' | \'%\' | \'&\' | \'*\' ;\ndigit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;\nletter = "A" | "B" | "C" | "D" | "E" | "F" | "G"\n | "H" | "I" | "J" | "K" | "L" | "M" | "N"\n | "O" | "P" | "Q" | "R" | "S" | "T" | "U"\n | "V" | "W" | "X" | "Y" | "Z" ;\n', - 'elixir': - 'defrecord Person, first_name: nil, last_name: "Dudington" do\n def name record do # huh ?\n "#{record.first_name} #{record.last_name}"\n end\nend\n\ndefrecord User, name: "José", age: 25\n\nguy = Person.new first_name: "Guy"\nguy.name\n\ndefmodule ListServer do\n @moduledoc """\n This module provides an easy to use ListServer, useful for keeping\n lists of things.\n """\n use GenServer.Behaviour\n alias Foo.Bar\n\n ### Public API\n @doc """\n Starts and links a new ListServer, returning {:ok, pid}\n\n ## Example\n\n iex> {:ok, pid} = ListServer.start_link\n\n """\n def start_link do\n :gen_server.start_link({:local, :list}, __MODULE__, [], [])\n end\n\n ### GenServer API\n def init(list) do\n {:ok, list}\n end\n\n # Clear the list\n def handle_cast :clear, list do\n {:noreply, []}\n end\nend\n\n{:ok, pid} = ListServer.start_link\npid <- {:foo, "bar"}\n\ngreeter = fn(x) -> IO.puts "hey #{x}" end\ngreeter.("Bob")\n\n', - 'elm': - 'import Browser\nimport Html exposing (div, button, text)\nimport Html.Events exposing (onClick)\n\ntype Msg\n = Increment\n\nmain =\n Browser.sandbox\n { init = 0\n , update = \\msg model -> model + 1\n , view = view\n }\n\nview model =\n div []\n [ div [] [ text (String.fromInt model) ]\n , button [ onClick Increment ] [ text "+" ]\n ]\n\nchars =\n String.cons \'C\' <| String.cons \'h\' <| "ars"\n', - 'erb': - '<%# this is a comment %>\n\n<% @posts.each do |post| %>\n

<%= link_to post.title, post %>

\n<% end %>\n\n<%- available_things = things.select(&:available?) -%>\n<%%- x = 1 + 2 -%%>\n<%% value = \'real string #{@value}\' %%>\n<%%= available_things.inspect %%>\n', - 'erlang': - '-module(ssh_cli).\n\n-behaviour(ssh_channel).\n\n-include("ssh.hrl").\n%% backwards compatibility\n-export([listen/1, listen/2, listen/3, listen/4, stop/1]).\n\nif L =/= [] -> % If L is not empty\n sum(L) / count(L);\ntrue ->\n error\nend.\n\n%% state\n-record(state, {\n cm,\n channel\n }).\n\n-spec foo(integer()) -> integer().\nfoo(X) -> 1 + X.\n\ntest(Foo)->Foo.\n\ninit([Shell, Exec]) ->\n {ok, #state{shell = Shell, exec = Exec}};\ninit([Shell]) ->\n false = not true,\n io:format("Hello, \\"~p!~n", [atom_to_list(\'World\')]),\n {ok, #state{shell = Shell}}.\n\nconcat([Single]) -> Single;\nconcat(RList) ->\n EpsilonFree = lists:filter(\n fun (Element) ->\n case Element of\n epsilon -> false;\n _ -> true\n end\n end,\n RList),\n case EpsilonFree of\n [Single] -> Single;\n Other -> {concat, Other}\n end.\n\nunion_dot_union({union, _}=U1, {union, _}=U2) ->\n union(lists:flatten(\n lists:map(\n fun (X1) ->\n lists:map(\n fun (X2) ->\n concat([X1, X2])\n end,\n union_to_list(U2)\n )\n end,\n union_to_list(U1)\n ))).\n', - 'erlang-repl': - '1> Str = "abcd".\n"abcd"\n2> L = test:length(Str).\n4\n3> Descriptor = {L, list_to_atom(Str)}.\n{4,abcd}\n4> L.\n4\n5> b().\nDescriptor = {4,abcd}\nL = 4\nStr = "abcd"\nok\n6> f(L).\nok\n7> b().\nDescriptor = {4,abcd}\nStr = "abcd"\nok\n8> {L, _} = Descriptor.\n{4,abcd}\n9> L.\n4\n10> 2#101.\n5\n11> 1.85e+3.\n1850\n', - 'excel': '=IF(C10 <= 275.5, "Unprofitable", "Profitable")', - 'fix': - '8=FIX.4.2␁9=0␁35=8␁49=SENDERTEST␁56=TARGETTEST␁34=00000001526␁52=20120429-13:30:08.137␁1=ABC12345␁11=2012abc1234␁14=100␁17=201254321␁20=0␁30=NYSE␁31=108.20␁32=100␁38=100␁39=2␁40=1␁47=A␁54=5␁55=BRK␁59=2␁60=20120429-13:30:08.000␁65=B␁76=BROKER␁84=0␁100=NYSE␁111=100␁150=2␁151=0␁167=CS␁377=N␁10000=SampleCustomTag␁10=123␁\n\n8=FIX.4.29=035=849=SENDERTEST56=TARGETTEST34=0000000152652=20120429-13:30:08.1371=ABC1234511=2012abc123414=10017=20125432120=030=NYSE31=108.2032=10038=10039=240=147=A54=555=BRK59=260=20120429-13:30:08.00065=B76=BROKER84=0100=NYSE111=100150=2151=0167=CS377=N10000=SampleCustomTag10=123\n', - 'flix': - '/**\n * An example of Flix for syntax highlighting.\n */\n\n// Here is a namespace.\nnamespace a.b.c {\n\n // Here are some literals.\n def b: Bool = true\n def c: Char = \'a\'\n def f: Float = 1.23\n def i: Int = 42\n def s: Str = "string"\n\n // Here are some relations.\n rel LitStm(r: Str, c: Int)\n rel AddStm(r: Str, x: Str, y: Str)\n rel DivStm(r: Str, x: Str, y: Str)\n\n // Here is a lattice.\n lat LocalVar(k: Str, v: Constant)\n\n // Here is an index.\n index LitStm{{r}, {r, c}}\n\n // Here is an enum.\n enum Constant {\n case Top,\n\n case Cst(Int),\n\n case Bot\n }\n\n // Here is a function.\n def leq(e1: Constant, e2: Constant): Bool = match (e1, e2) with {\n case (Constant.Bot, _) => true\n case (Constant.Cst(n1), Constant.Cst(n2)) => n1 == n2\n case (_, Constant.Top) => true\n case _ => false\n }\n\n // Here are some rules.\n LocalVar(r, alpha(c)) :- LitStm(r, c).\n\n LocalVar(r, sum(v1, v2)) :- AddStm(r, x, y),\n LocalVar(x, v1),\n LocalVar(y, v2).\n}\n', - 'fortran': - 'subroutine test_sub(k)\n implicit none\n\n !===============================\n ! This is a test subroutine\n !===============================\n\n integer, intent(in) :: k\n double precision, allocatable :: a(:)\n integer, parameter :: nmax=10\n integer :: i\n\n allocate (a(nmax))\n\n do i=1,nmax\n a(i) = dble(i)*5.d0\n enddo\n\n print *, \'Hello world\'\n write (*,*) a(:)\n\nend subroutine test_sub\n', - 'fsharp': - 'open System\n\n// Single line comment...\n(*\n This is a\n multiline comment.\n*)\nlet checkList alist =\n match alist with\n | [] -> 0\n | [a] -> 1\n | [a; b] -> 2\n | [a; b; c] -> 3\n | _ -> failwith "List is too big!"\n\n\nlet text = "Some text..."\nlet text2 = @"A ""verbatim"" string..."\nlet catalog = """\nSome "long" string...\n"""\n\nlet rec fib x = if x <= 2 then 1 else fib(x-1) + fib(x-2)\n\nlet fibs =\n Async.Parallel [ for i in 0..40 -> async { return fib(i) } ]\n |> Async.RunSynchronously\n\ntype Sprocket(gears) =\n member this.Gears : int = gears\n\n[]\ntype Animal =\n abstract Speak : unit -> unit\n\ntype Widget =\n | RedWidget\n | GreenWidget\n\ntype Point = {X: float; Y: float;}\n\n[]\ntype s\nlet minutte = 60\n\ntype DefaultMailbox<\'a>() =\n let mutable inbox = ConcurrentQueue<\'a>()\n let awaitMsg = new AutoResetEvent(false)\n', - 'gams': - 'SETS\n I canning plants / SEATTLE, SAN-DIEGO /\n J markets / NEW-YORK, CHICAGO, TOPEKA / ;\nPARAMETERS\n A(I) capacity of plant i in cases\n / SEATTLE 350\n SAN-DIEGO 600 /\n B(J) demand at market j in cases\n / NEW-YORK 325\n CHICAGO 300\n TOPEKA 275 / ;\nTABLE D(I,J) distance in thousands of miles\n NEW-YORK CHICAGO TOPEKA\n SEATTLE 2.5 1.7 1.8\n SAN-DIEGO 2.5 1.8 1.4 ;\nSCALAR F freight in dollars per case per thousand miles /90/ ;\nPARAMETER C(I,J) transport cost in thousands of dollars per case ;\n C(I,J) = F * D(I,J) / 1000 ;\nVARIABLES\n X(I,J) shipment quantities in cases\n Z total transportation costs in thousands of dollars ;\nPOSITIVE VARIABLE X ;\nEQUATIONS\n COST define objective function\n SUPPLY(I) observe supply limit at plant i\n DEMAND(J) satisfy demand at market j ;\nCOST .. Z =E= SUM((I,J), C(I,J)*X(I,J)) ;\nSUPPLY(I) .. SUM(J, X(I,J)) =L= A(I) ;\nDEMAND(J) .. SUM(I, X(I,J)) =G= B(J) ;\nMODEL TRANSPORT /ALL/ ;\nSOLVE TRANSPORT USING LP MINIMIZING Z ;\n', - 'gauss': - '// This is a test\n#include pv.sdf\n\nproc (1) = calc(local__row, fin);\n if local__row;\n nr = local__row;\n else;\n k = colsf(fin);\n nr = floor(minc(maxbytes/(k*8*3.5)|maxvec/(k+1)));\n endif;\n retp(nr);\nendp;\n\ns = "{% test string %}";\n\nfn twopi=pi*2;\n\n/* Takes in multiple numbers.\n Output sum */\nkeyword add(str);\n local tok,sum;\n sum = 0;\n do until str \$== "";\n { tok, str } = token(str);\n sum = sum + stof(tok);\n endo;\n print "Sum is: " sum;\nendp;\n', - 'gcode': - 'O003 (DIAMOND SQUARE)\nN2 G54 G90 G49 G80\nN3 M6 T1 (1.ENDMILL)\nN4 M3 S1800\nN5 G0 X-.6 Y2.050\nN6 G43 H1 Z.1\nN7 G1 Z-.3 F50.\nN8 G41 D1 Y1.45\nN9 G1 X0 F20.\nN10 G2 J-1.45\n(CUTTER COMP CANCEL)\nN11 G1 Z-.2 F50.\nN12 Y-.990\nN13 G40\nN14 G0 X-.6 Y1.590\nN15 G0 Z.1\nN16 M5 G49 G28 G91 Z0\nN17 CALL O9456\nN18 #500=0.004\nN19 #503=[#500+#501]\nN20 VC45=0.0006\nVS4=0.0007\nN21 G90 G10 L20 P3 X5.Y4. Z6.567\nN22 G0 X5000\nN23 IF [#1 LT 0.370] GOTO 49\nN24 X-0.678 Y+.990\nN25 G84.3 X-0.1\nN26 #4=#5*COS[45]\nN27 #4=#5*SIN[45]\nN28 VZOFZ=652.9658\n%\n', - 'gherkin': - '# language: en\nFeature: Addition\n In order to avoid silly mistakes\n As a math idiot\n I want to be told the sum of two numbers\n\n @this_is_a_tag\n Scenario Outline: Add two numbers\n * I have a calculator\n Given I have entered into the calculator\n And I have entered into the calculator\n When I press