├── ankii_flutter_gradient ├── .gitignore ├── .metadata ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── ankii │ │ │ │ │ └── ankii_flutter_gradient │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── assets │ ├── linear_code_template │ └── transparent.jpg ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.swift │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── Runner-Bridging-Header.h ├── lib │ ├── main.dart │ └── src │ │ ├── global │ │ └── theme │ │ │ └── global_theme.dart │ │ ├── helpers │ │ ├── gradient_helper.dart │ │ └── string_helper.dart │ │ ├── screens │ │ └── main_screen.dart │ │ ├── services │ │ └── wallpaper_service.dart │ │ └── widgets │ │ ├── circular_slider.dart │ │ ├── increase_slider.dart │ │ └── no_glowable_scroll_view.dart ├── pubspec.lock ├── pubspec.yaml ├── test │ └── widget_test.dart └── web │ ├── favicon.png │ ├── icons │ ├── Icon-192.png │ └── Icon-512.png │ ├── index.html │ └── manifest.json ├── app_icon.png ├── app_icon.psd └── web ├── .last_build_id ├── assets ├── AssetManifest.json ├── FontManifest.json ├── NOTICES ├── assets │ └── transparent.jpg ├── fonts │ └── MaterialIcons-Regular.otf └── packages │ ├── cupertino_icons │ └── assets │ │ └── CupertinoIcons.ttf │ ├── font_awesome_flutter │ └── lib │ │ └── fonts │ │ ├── fa-brands-400.ttf │ │ ├── fa-regular-400.ttf │ │ └── fa-solid-900.ttf │ └── wakelock_web │ └── assets │ └── no_sleep.js ├── favicon.png ├── flutter_service_worker.js ├── icons ├── Icon-192.png └── Icon-512.png ├── index.html ├── main.dart.js ├── manifest.json └── version.json /ankii_flutter_gradient/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: fba99f6cf9a14512e461e3122c8ddfaa25394e89 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/README.md: -------------------------------------------------------------------------------- 1 | # ankii_flutter_gradient 2 | 3 | A new Flutter application. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion 28 30 | 31 | sourceSets { 32 | main.java.srcDirs += 'src/main/kotlin' 33 | } 34 | 35 | lintOptions { 36 | disable 'InvalidPackage' 37 | } 38 | 39 | defaultConfig { 40 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 41 | applicationId "com.ankii.ankii_flutter_gradient" 42 | minSdkVersion 16 43 | targetSdkVersion 28 44 | versionCode flutterVersionCode.toInteger() 45 | versionName flutterVersionName 46 | } 47 | 48 | buildTypes { 49 | release { 50 | // TODO: Add your own signing config for the release build. 51 | // Signing with the debug keys for now, so `flutter run --release` works. 52 | signingConfig signingConfigs.debug 53 | } 54 | } 55 | } 56 | 57 | flutter { 58 | source '../..' 59 | } 60 | 61 | dependencies { 62 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 63 | } 64 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 8 | 9 | 13 | 14 | 21 | 25 | 29 | 34 | 38 | 39 | 40 | 41 | 42 | 43 | 45 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/kotlin/com/ankii/ankii_flutter_gradient/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.ankii.ankii_flutter_gradient 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.3.50' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.5.0' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/assets/linear_code_template: -------------------------------------------------------------------------------- 1 |

LinearGradient

2 |

(

3 |

colors: $colors,

4 |

stops: $stops,

5 |

begin: Alignment($beginX, $beginY),

6 |

end: Alignment($endX, $endY)

7 |

)

-------------------------------------------------------------------------------- /ankii_flutter_gradient/assets/transparent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/assets/transparent.jpg -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | /* End PBXBuildFile section */ 17 | 18 | /* Begin PBXCopyFilesBuildPhase section */ 19 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 20 | isa = PBXCopyFilesBuildPhase; 21 | buildActionMask = 2147483647; 22 | dstPath = ""; 23 | dstSubfolderSpec = 10; 24 | files = ( 25 | ); 26 | name = "Embed Frameworks"; 27 | runOnlyForDeploymentPostprocessing = 0; 28 | }; 29 | /* End PBXCopyFilesBuildPhase section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 33 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 34 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 35 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 36 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 37 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 38 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 39 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 40 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 43 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 44 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | ); 53 | runOnlyForDeploymentPostprocessing = 0; 54 | }; 55 | /* End PBXFrameworksBuildPhase section */ 56 | 57 | /* Begin PBXGroup section */ 58 | 9740EEB11CF90186004384FC /* Flutter */ = { 59 | isa = PBXGroup; 60 | children = ( 61 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 62 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 63 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 64 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 65 | ); 66 | name = Flutter; 67 | sourceTree = ""; 68 | }; 69 | 97C146E51CF9000F007C117D = { 70 | isa = PBXGroup; 71 | children = ( 72 | 9740EEB11CF90186004384FC /* Flutter */, 73 | 97C146F01CF9000F007C117D /* Runner */, 74 | 97C146EF1CF9000F007C117D /* Products */, 75 | ); 76 | sourceTree = ""; 77 | }; 78 | 97C146EF1CF9000F007C117D /* Products */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 97C146EE1CF9000F007C117D /* Runner.app */, 82 | ); 83 | name = Products; 84 | sourceTree = ""; 85 | }; 86 | 97C146F01CF9000F007C117D /* Runner */ = { 87 | isa = PBXGroup; 88 | children = ( 89 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 90 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 91 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 92 | 97C147021CF9000F007C117D /* Info.plist */, 93 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 94 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 95 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 96 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 97 | ); 98 | path = Runner; 99 | sourceTree = ""; 100 | }; 101 | /* End PBXGroup section */ 102 | 103 | /* Begin PBXNativeTarget section */ 104 | 97C146ED1CF9000F007C117D /* Runner */ = { 105 | isa = PBXNativeTarget; 106 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 107 | buildPhases = ( 108 | 9740EEB61CF901F6004384FC /* Run Script */, 109 | 97C146EA1CF9000F007C117D /* Sources */, 110 | 97C146EB1CF9000F007C117D /* Frameworks */, 111 | 97C146EC1CF9000F007C117D /* Resources */, 112 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 113 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 114 | ); 115 | buildRules = ( 116 | ); 117 | dependencies = ( 118 | ); 119 | name = Runner; 120 | productName = Runner; 121 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 122 | productType = "com.apple.product-type.application"; 123 | }; 124 | /* End PBXNativeTarget section */ 125 | 126 | /* Begin PBXProject section */ 127 | 97C146E61CF9000F007C117D /* Project object */ = { 128 | isa = PBXProject; 129 | attributes = { 130 | LastUpgradeCheck = 1020; 131 | ORGANIZATIONNAME = ""; 132 | TargetAttributes = { 133 | 97C146ED1CF9000F007C117D = { 134 | CreatedOnToolsVersion = 7.3.1; 135 | LastSwiftMigration = 1100; 136 | }; 137 | }; 138 | }; 139 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 140 | compatibilityVersion = "Xcode 9.3"; 141 | developmentRegion = en; 142 | hasScannedForEncodings = 0; 143 | knownRegions = ( 144 | en, 145 | Base, 146 | ); 147 | mainGroup = 97C146E51CF9000F007C117D; 148 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 149 | projectDirPath = ""; 150 | projectRoot = ""; 151 | targets = ( 152 | 97C146ED1CF9000F007C117D /* Runner */, 153 | ); 154 | }; 155 | /* End PBXProject section */ 156 | 157 | /* Begin PBXResourcesBuildPhase section */ 158 | 97C146EC1CF9000F007C117D /* Resources */ = { 159 | isa = PBXResourcesBuildPhase; 160 | buildActionMask = 2147483647; 161 | files = ( 162 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 163 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 164 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 165 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 166 | ); 167 | runOnlyForDeploymentPostprocessing = 0; 168 | }; 169 | /* End PBXResourcesBuildPhase section */ 170 | 171 | /* Begin PBXShellScriptBuildPhase section */ 172 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 173 | isa = PBXShellScriptBuildPhase; 174 | buildActionMask = 2147483647; 175 | files = ( 176 | ); 177 | inputPaths = ( 178 | ); 179 | name = "Thin Binary"; 180 | outputPaths = ( 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | shellPath = /bin/sh; 184 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 185 | }; 186 | 9740EEB61CF901F6004384FC /* Run Script */ = { 187 | isa = PBXShellScriptBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | ); 191 | inputPaths = ( 192 | ); 193 | name = "Run Script"; 194 | outputPaths = ( 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | shellPath = /bin/sh; 198 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 199 | }; 200 | /* End PBXShellScriptBuildPhase section */ 201 | 202 | /* Begin PBXSourcesBuildPhase section */ 203 | 97C146EA1CF9000F007C117D /* Sources */ = { 204 | isa = PBXSourcesBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 208 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 209 | ); 210 | runOnlyForDeploymentPostprocessing = 0; 211 | }; 212 | /* End PBXSourcesBuildPhase section */ 213 | 214 | /* Begin PBXVariantGroup section */ 215 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 97C146FB1CF9000F007C117D /* Base */, 219 | ); 220 | name = Main.storyboard; 221 | sourceTree = ""; 222 | }; 223 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 224 | isa = PBXVariantGroup; 225 | children = ( 226 | 97C147001CF9000F007C117D /* Base */, 227 | ); 228 | name = LaunchScreen.storyboard; 229 | sourceTree = ""; 230 | }; 231 | /* End PBXVariantGroup section */ 232 | 233 | /* Begin XCBuildConfiguration section */ 234 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 235 | isa = XCBuildConfiguration; 236 | buildSettings = { 237 | ALWAYS_SEARCH_USER_PATHS = NO; 238 | CLANG_ANALYZER_NONNULL = YES; 239 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 240 | CLANG_CXX_LIBRARY = "libc++"; 241 | CLANG_ENABLE_MODULES = YES; 242 | CLANG_ENABLE_OBJC_ARC = YES; 243 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 244 | CLANG_WARN_BOOL_CONVERSION = YES; 245 | CLANG_WARN_COMMA = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INFINITE_RECURSION = YES; 252 | CLANG_WARN_INT_CONVERSION = YES; 253 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 254 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 255 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 256 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 257 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 258 | CLANG_WARN_STRICT_PROTOTYPES = YES; 259 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 260 | CLANG_WARN_UNREACHABLE_CODE = YES; 261 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 262 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 263 | COPY_PHASE_STRIP = NO; 264 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 265 | ENABLE_NS_ASSERTIONS = NO; 266 | ENABLE_STRICT_OBJC_MSGSEND = YES; 267 | GCC_C_LANGUAGE_STANDARD = gnu99; 268 | GCC_NO_COMMON_BLOCKS = YES; 269 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 270 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 271 | GCC_WARN_UNDECLARED_SELECTOR = YES; 272 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 273 | GCC_WARN_UNUSED_FUNCTION = YES; 274 | GCC_WARN_UNUSED_VARIABLE = YES; 275 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 276 | MTL_ENABLE_DEBUG_INFO = NO; 277 | SDKROOT = iphoneos; 278 | SUPPORTED_PLATFORMS = iphoneos; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | VALIDATE_PRODUCT = YES; 281 | }; 282 | name = Profile; 283 | }; 284 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 285 | isa = XCBuildConfiguration; 286 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | CLANG_ENABLE_MODULES = YES; 290 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 291 | ENABLE_BITCODE = NO; 292 | FRAMEWORK_SEARCH_PATHS = ( 293 | "$(inherited)", 294 | "$(PROJECT_DIR)/Flutter", 295 | ); 296 | INFOPLIST_FILE = Runner/Info.plist; 297 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 298 | LIBRARY_SEARCH_PATHS = ( 299 | "$(inherited)", 300 | "$(PROJECT_DIR)/Flutter", 301 | ); 302 | PRODUCT_BUNDLE_IDENTIFIER = com.ankii.ankiiFlutterGradient; 303 | PRODUCT_NAME = "$(TARGET_NAME)"; 304 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 305 | SWIFT_VERSION = 5.0; 306 | VERSIONING_SYSTEM = "apple-generic"; 307 | }; 308 | name = Profile; 309 | }; 310 | 97C147031CF9000F007C117D /* Debug */ = { 311 | isa = XCBuildConfiguration; 312 | buildSettings = { 313 | ALWAYS_SEARCH_USER_PATHS = NO; 314 | CLANG_ANALYZER_NONNULL = YES; 315 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 316 | CLANG_CXX_LIBRARY = "libc++"; 317 | CLANG_ENABLE_MODULES = YES; 318 | CLANG_ENABLE_OBJC_ARC = YES; 319 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 320 | CLANG_WARN_BOOL_CONVERSION = YES; 321 | CLANG_WARN_COMMA = YES; 322 | CLANG_WARN_CONSTANT_CONVERSION = YES; 323 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 324 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 325 | CLANG_WARN_EMPTY_BODY = YES; 326 | CLANG_WARN_ENUM_CONVERSION = YES; 327 | CLANG_WARN_INFINITE_RECURSION = YES; 328 | CLANG_WARN_INT_CONVERSION = YES; 329 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 330 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 331 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 332 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 333 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 334 | CLANG_WARN_STRICT_PROTOTYPES = YES; 335 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 336 | CLANG_WARN_UNREACHABLE_CODE = YES; 337 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 338 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 339 | COPY_PHASE_STRIP = NO; 340 | DEBUG_INFORMATION_FORMAT = dwarf; 341 | ENABLE_STRICT_OBJC_MSGSEND = YES; 342 | ENABLE_TESTABILITY = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_NO_COMMON_BLOCKS = YES; 346 | GCC_OPTIMIZATION_LEVEL = 0; 347 | GCC_PREPROCESSOR_DEFINITIONS = ( 348 | "DEBUG=1", 349 | "$(inherited)", 350 | ); 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 358 | MTL_ENABLE_DEBUG_INFO = YES; 359 | ONLY_ACTIVE_ARCH = YES; 360 | SDKROOT = iphoneos; 361 | TARGETED_DEVICE_FAMILY = "1,2"; 362 | }; 363 | name = Debug; 364 | }; 365 | 97C147041CF9000F007C117D /* Release */ = { 366 | isa = XCBuildConfiguration; 367 | buildSettings = { 368 | ALWAYS_SEARCH_USER_PATHS = NO; 369 | CLANG_ANALYZER_NONNULL = YES; 370 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 371 | CLANG_CXX_LIBRARY = "libc++"; 372 | CLANG_ENABLE_MODULES = YES; 373 | CLANG_ENABLE_OBJC_ARC = YES; 374 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 375 | CLANG_WARN_BOOL_CONVERSION = YES; 376 | CLANG_WARN_COMMA = YES; 377 | CLANG_WARN_CONSTANT_CONVERSION = YES; 378 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 379 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 380 | CLANG_WARN_EMPTY_BODY = YES; 381 | CLANG_WARN_ENUM_CONVERSION = YES; 382 | CLANG_WARN_INFINITE_RECURSION = YES; 383 | CLANG_WARN_INT_CONVERSION = YES; 384 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 385 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 386 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 387 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 388 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 389 | CLANG_WARN_STRICT_PROTOTYPES = YES; 390 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 391 | CLANG_WARN_UNREACHABLE_CODE = YES; 392 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 393 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 394 | COPY_PHASE_STRIP = NO; 395 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 396 | ENABLE_NS_ASSERTIONS = NO; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | GCC_C_LANGUAGE_STANDARD = gnu99; 399 | GCC_NO_COMMON_BLOCKS = YES; 400 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 401 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 402 | GCC_WARN_UNDECLARED_SELECTOR = YES; 403 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 404 | GCC_WARN_UNUSED_FUNCTION = YES; 405 | GCC_WARN_UNUSED_VARIABLE = YES; 406 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 407 | MTL_ENABLE_DEBUG_INFO = NO; 408 | SDKROOT = iphoneos; 409 | SUPPORTED_PLATFORMS = iphoneos; 410 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 411 | TARGETED_DEVICE_FAMILY = "1,2"; 412 | VALIDATE_PRODUCT = YES; 413 | }; 414 | name = Release; 415 | }; 416 | 97C147061CF9000F007C117D /* Debug */ = { 417 | isa = XCBuildConfiguration; 418 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 419 | buildSettings = { 420 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 421 | CLANG_ENABLE_MODULES = YES; 422 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 423 | ENABLE_BITCODE = NO; 424 | FRAMEWORK_SEARCH_PATHS = ( 425 | "$(inherited)", 426 | "$(PROJECT_DIR)/Flutter", 427 | ); 428 | INFOPLIST_FILE = Runner/Info.plist; 429 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 430 | LIBRARY_SEARCH_PATHS = ( 431 | "$(inherited)", 432 | "$(PROJECT_DIR)/Flutter", 433 | ); 434 | PRODUCT_BUNDLE_IDENTIFIER = com.ankii.ankiiFlutterGradient; 435 | PRODUCT_NAME = "$(TARGET_NAME)"; 436 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 437 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 438 | SWIFT_VERSION = 5.0; 439 | VERSIONING_SYSTEM = "apple-generic"; 440 | }; 441 | name = Debug; 442 | }; 443 | 97C147071CF9000F007C117D /* Release */ = { 444 | isa = XCBuildConfiguration; 445 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 446 | buildSettings = { 447 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 448 | CLANG_ENABLE_MODULES = YES; 449 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 450 | ENABLE_BITCODE = NO; 451 | FRAMEWORK_SEARCH_PATHS = ( 452 | "$(inherited)", 453 | "$(PROJECT_DIR)/Flutter", 454 | ); 455 | INFOPLIST_FILE = Runner/Info.plist; 456 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 457 | LIBRARY_SEARCH_PATHS = ( 458 | "$(inherited)", 459 | "$(PROJECT_DIR)/Flutter", 460 | ); 461 | PRODUCT_BUNDLE_IDENTIFIER = com.ankii.ankiiFlutterGradient; 462 | PRODUCT_NAME = "$(TARGET_NAME)"; 463 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 464 | SWIFT_VERSION = 5.0; 465 | VERSIONING_SYSTEM = "apple-generic"; 466 | }; 467 | name = Release; 468 | }; 469 | /* End XCBuildConfiguration section */ 470 | 471 | /* Begin XCConfigurationList section */ 472 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 473 | isa = XCConfigurationList; 474 | buildConfigurations = ( 475 | 97C147031CF9000F007C117D /* Debug */, 476 | 97C147041CF9000F007C117D /* Release */, 477 | 249021D3217E4FDB00AE95B9 /* Profile */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 483 | isa = XCConfigurationList; 484 | buildConfigurations = ( 485 | 97C147061CF9000F007C117D /* Debug */, 486 | 97C147071CF9000F007C117D /* Release */, 487 | 249021D4217E4FDB00AE95B9 /* Profile */, 488 | ); 489 | defaultConfigurationIsVisible = 0; 490 | defaultConfigurationName = Release; 491 | }; 492 | /* End XCConfigurationList section */ 493 | }; 494 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 495 | } 496 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | 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. -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ankii_flutter_gradient 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter/services.dart'; 3 | 4 | import 'src/screens/main_screen.dart'; 5 | 6 | void main() { 7 | WidgetsFlutterBinding.ensureInitialized(); 8 | SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(statusBarColor: Colors.transparent)); 9 | runApp(MyApp()); 10 | } 11 | 12 | class MyApp extends StatelessWidget { 13 | // This widget is the root of your application. 14 | @override 15 | Widget build(BuildContext context) { 16 | return MaterialApp( 17 | debugShowCheckedModeBanner: false, 18 | title: 'GRADiiENT', 19 | theme: ThemeData( 20 | // This is the theme of your application. 21 | // 22 | // Try running your application with "flutter run". You'll see the 23 | // application has a blue toolbar. Then, without quitting the app, try 24 | // changing the primarySwatch below to Colors.green and then invoke 25 | // "hot reload" (press "r" in the console where you ran "flutter run", 26 | // or simply save your changes to "hot reload" in a Flutter IDE). 27 | // Notice that the counter didn't reset back to zero; the application 28 | // is not restarted. 29 | primarySwatch: Colors.blue, 30 | // This makes the visual density adapt to the platform that you run 31 | // the app on. For desktop platforms, the controls will be smaller and 32 | // closer together (more dense) than on mobile platforms. 33 | visualDensity: VisualDensity.adaptivePlatformDensity, 34 | ), 35 | home: MyHomePage(), 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/global/theme/global_theme.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | const Color PRIMARY_COLOR = Colors.black; 4 | const Color BACKGROUND_COLOR = Color(0xffECF0F3); 5 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/helpers/gradient_helper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:flutter/material.dart'; 3 | 4 | 5 | class AnKiiDegreeAlignment{ 6 | final Alignment begin; 7 | final Alignment end; 8 | 9 | AnKiiDegreeAlignment(this.begin, this.end); 10 | } 11 | 12 | class GradientHelper { 13 | static AnKiiDegreeAlignment calcGradientAlignment(double degree) { 14 | 15 | Alignment start = Alignment(0, -1); 16 | double xEnd; 17 | double yEnd; 18 | 19 | double degreeTemp = degree.abs(); 20 | final double radian = (degreeTemp * pi) / 180; 21 | if (degreeTemp < 90) { 22 | xEnd = sin((pi / 2) - radian); 23 | yEnd = sin(radian); 24 | } else if (degreeTemp > 90) { 25 | xEnd = sin(radian - (pi / 2)); 26 | yEnd = sin((pi / 2) - (radian - (pi / 2))); 27 | } else { 28 | xEnd = 0; 29 | yEnd = 1; 30 | } 31 | if (degree >= 90) { 32 | final Alignment end = Alignment(yEnd, xEnd); 33 | start = Alignment(end.x * -1, end.y * -1); 34 | 35 | return AnKiiDegreeAlignment(start, end); 36 | } else { 37 | final Alignment end = Alignment(yEnd, -xEnd); 38 | start = Alignment(-end.x, -end.y); 39 | 40 | return AnKiiDegreeAlignment(start, end); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/helpers/string_helper.dart: -------------------------------------------------------------------------------- 1 | extension StringHelper on String { 2 | String withOutHtmlTag() { 3 | RegExp exp = RegExp(r"<[^>]*>", multiLine: true, caseSensitive: true); 4 | 5 | return this.replaceAll(exp, ''); 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/screens/main_screen.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:math'; 3 | import 'dart:ui' as ui; 4 | 5 | import 'package:ankii_flutter_gradient/src/helpers/string_helper.dart'; 6 | import 'package:ankii_flutter_gradient/src/services/wallpaper_service.dart'; 7 | import 'package:ankii_flutter_gradient/src/widgets/circular_slider.dart'; 8 | import 'package:ankii_flutter_gradient/src/widgets/increase_slider.dart'; 9 | import 'package:ankii_flutter_gradient/src/widgets/no_glowable_scroll_view.dart'; 10 | import 'package:flutter/cupertino.dart'; 11 | import 'package:flutter/material.dart'; 12 | import 'package:flutter/services.dart'; 13 | 14 | import 'package:flutter_colorpicker/flutter_colorpicker.dart'; 15 | import 'package:flutter_html/flutter_html.dart'; 16 | import 'package:flutter_html/style.dart'; 17 | import 'package:flutter_spinkit/flutter_spinkit.dart'; 18 | import 'package:font_awesome_flutter/font_awesome_flutter.dart'; 19 | import 'package:permission_handler/permission_handler.dart'; 20 | import 'package:reorderables/reorderables.dart'; 21 | import 'package:share/share.dart'; 22 | import 'package:wallpaper_manager/wallpaper_manager.dart'; 23 | 24 | import '../helpers/gradient_helper.dart'; 25 | 26 | class MyHomePage extends StatefulWidget { 27 | @override 28 | _MyHomePageState createState() => _MyHomePageState(); 29 | } 30 | 31 | class _MyHomePageState extends State { 32 | int _type = 0; 33 | List gradientColors = [ 34 | AnKiiGradientColor(color: Colors.red, stop: 0), 35 | AnKiiGradientColor(color: Colors.blue, stop: 1) 36 | ]; 37 | double degreeValue = 180; 38 | Alignment begin = Alignment.topCenter; 39 | Alignment end = Alignment.bottomCenter; 40 | bool viewFull = false; 41 | bool _randomLoading = false; 42 | int currentColorIndex = 0; 43 | Color itemColor = Colors.white; 44 | 45 | // SUB WIDGETS 46 | Widget gradientCard() { 47 | double width = MediaQuery.of(context).size.width; 48 | double height = 150; 49 | double padding = 10; 50 | Gradient gradient = _type == 0 51 | ? LinearGradient( 52 | colors: [...gradientColors.map((e) => e.color).toList()], 53 | stops: [...gradientColors.map((e) => e.stop).toList()], 54 | begin: begin, 55 | end: end, 56 | ) 57 | : RadialGradient( 58 | colors: [...gradientColors.map((e) => e.color).toList()], 59 | stops: [...gradientColors.map((e) => e.stop).toList()]); 60 | 61 | return Card( 62 | elevation: viewFull ? 0 : 5, 63 | shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), 64 | color: Colors.transparent, 65 | child: AnimatedContainer( 66 | duration: Duration(milliseconds: 500), 67 | height: height, 68 | width: width, 69 | decoration: BoxDecoration( 70 | color: Colors.white, 71 | borderRadius: BorderRadius.circular(10), 72 | ), 73 | alignment: Alignment.center, 74 | padding: EdgeInsets.all(padding), 75 | child: Row( 76 | children: [ 77 | Expanded( 78 | child: AnimatedContainer( 79 | duration: Duration(milliseconds: 200), 80 | decoration: BoxDecoration( 81 | gradient: SweepGradient( 82 | center: FractionalOffset.center, 83 | startAngle: 0, 84 | endAngle: degreeValue * 2 * pi / 360, 85 | colors: [ 86 | ...gradientColors.map((e) => e.color).toList() 87 | ], 88 | stops: [ 89 | ...gradientColors.map((e) => e.stop).toList() 90 | ], 91 | ), 92 | border: Border.all(color: itemColor, width: 2)), 93 | child: Center( 94 | child: Text( 95 | 'Swipe', 96 | style: TextStyle(color: itemColor), 97 | )), 98 | ), 99 | ), 100 | SizedBox( 101 | width: padding, 102 | ), 103 | Expanded( 104 | child: AnimatedContainer( 105 | duration: Duration(milliseconds: 200), 106 | decoration: BoxDecoration( 107 | gradient: gradient.scale(0.5), 108 | border: Border.all(color: itemColor, width: 2)), 109 | child: Center( 110 | child: Text( 111 | 'Scale x2', 112 | style: TextStyle(color: itemColor), 113 | )), 114 | ), 115 | ), 116 | SizedBox( 117 | width: padding, 118 | ), 119 | Expanded( 120 | child: AnimatedContainer( 121 | duration: Duration(milliseconds: 200), 122 | decoration: BoxDecoration( 123 | border: Border.all(color: itemColor, width: 2)), 124 | child: Center( 125 | child: Text( 126 | 'Transparent', 127 | style: TextStyle(color: itemColor), 128 | )), 129 | ), 130 | ) 131 | ], 132 | ), 133 | ), 134 | ); 135 | } 136 | 137 | Widget _typeSwitcherButton({int index = 0, String text = ''}) { 138 | Gradient gradient = _type == 0 139 | ? LinearGradient( 140 | colors: [...gradientColors.map((e) => e.color).toList()]) 141 | : RadialGradient( 142 | colors: [...gradientColors.map((e) => e.color).toList()]); 143 | return GestureDetector( 144 | onTap: () { 145 | setState(() { 146 | if (_type != index) { 147 | _type = index; 148 | } 149 | }); 150 | }, 151 | child: Container( 152 | width: 100, 153 | decoration: BoxDecoration( 154 | border: Border.all(color: itemColor, width: 2), 155 | color: _type != index ? Colors.transparent : itemColor, 156 | borderRadius: BorderRadius.circular(5)), 157 | alignment: Alignment.center, 158 | padding: EdgeInsets.all(10), 159 | child: Text( 160 | text, 161 | style: TextStyle( 162 | color: _type != index ? itemColor : gradientColors[0].color), 163 | )), 164 | ); 165 | } 166 | 167 | Widget typeSwitcher() { 168 | return Container( 169 | padding: EdgeInsets.all(10), 170 | child: Row( 171 | mainAxisAlignment: MainAxisAlignment.center, 172 | children: [ 173 | _typeSwitcherButton(text: 'Linear', index: 0), 174 | SizedBox( 175 | width: 10, 176 | ), 177 | _typeSwitcherButton(text: 'Radial', index: 1), 178 | SizedBox( 179 | width: 10, 180 | ), 181 | _typeSwitcherButton(text: 'Swipe', index: 2), 182 | ], 183 | ), 184 | ); 185 | } 186 | 187 | Widget _linerOptionCard(Widget child) { 188 | Gradient gradient = _type == 0 189 | ? LinearGradient( 190 | colors: [...gradientColors.map((e) => e.color).toList()], 191 | stops: [...gradientColors.map((e) => e.stop).toList()], 192 | begin: begin, 193 | end: end) 194 | : RadialGradient( 195 | colors: [...gradientColors.map((e) => e.color).toList()], 196 | stops: [...gradientColors.map((e) => e.stop).toList()]); 197 | return Container( 198 | margin: EdgeInsets.symmetric(horizontal: 10), 199 | child: AnimatedContainer( 200 | duration: Duration(milliseconds: 500), 201 | constraints: 202 | BoxConstraints(minHeight: MediaQuery.of(context).size.width), 203 | padding: EdgeInsets.all(10), 204 | child: child)); 205 | } 206 | 207 | Widget linearOption() { 208 | return Container( 209 | padding: EdgeInsets.only(bottom: 100), 210 | child: _linerOptionCard( 211 | Wrap( 212 | alignment: WrapAlignment.center, 213 | children: [ 214 | _degreesSlider(), 215 | Container( 216 | margin: EdgeInsets.all(10), 217 | child: Column( 218 | mainAxisSize: MainAxisSize.min, 219 | children: [ 220 | _stopViewer(), 221 | SizedBox( 222 | height: 30, 223 | ), 224 | _colorModifyingStopSlider(), 225 | ], 226 | ), 227 | ), 228 | 229 | Container( 230 | margin: EdgeInsets.all(10), 231 | child: Column( 232 | mainAxisSize: MainAxisSize.min, 233 | children: [ 234 | Wrap( 235 | children: [_colorsList(), _addColorButton()], 236 | ), 237 | SizedBox( 238 | height: 30, 239 | ), 240 | _colorModifying() 241 | ], 242 | ), 243 | ), 244 | ], 245 | ), 246 | ), 247 | ); 248 | } 249 | 250 | Widget _addColorButton() { 251 | return InkWell( 252 | onTap: () { 253 | addColor(); 254 | }, 255 | child: Container( 256 | alignment: Alignment.center, 257 | height: 70, 258 | width: 70, 259 | child: Icon( 260 | FontAwesomeIcons.plusCircle, 261 | color: itemColor, 262 | ), 263 | ), 264 | ); 265 | } 266 | 267 | Widget _stopViewer() { 268 | double width = MediaQuery.of(context).size.width * 0.7; 269 | var gradient = LinearGradient( 270 | colors: [...gradientColors.map((e) => e.color).toList()], 271 | stops: [...gradientColors.map((e) => e.stop).toList()]); 272 | return Container( 273 | padding: EdgeInsets.symmetric(vertical: 5, horizontal: 5), 274 | height: 50, 275 | width: width, 276 | decoration: BoxDecoration( 277 | gradient: gradient, 278 | borderRadius: BorderRadius.circular(15), 279 | border: Border.all(color: itemColor, width: 2) 280 | // boxShadow: [BoxShadow(color: itemColor, blurRadius: 5)] 281 | ), 282 | child: Stack( 283 | children: [ 284 | ...gradientColors 285 | .asMap() 286 | .map((index, data) => MapEntry(index, 287 | __stopViewerIndicator(index, max: width, percent: data.stop))) 288 | .values 289 | .toList(), 290 | ], 291 | ), 292 | ); 293 | } 294 | 295 | Widget __stopViewerIndicator(int index, 296 | {double max = 1, double percent = 1}) { 297 | double width = 20; 298 | double padding = 10; 299 | return GestureDetector( 300 | onTapDown: (d) { 301 | setState(() { 302 | currentColorIndex = index; 303 | }); 304 | }, 305 | onHorizontalDragStart: (d) { 306 | setState(() { 307 | currentColorIndex = index; 308 | }); 309 | }, 310 | onHorizontalDragUpdate: (d) { 311 | double toIncrease = 0.01; 312 | if (d.delta.dx > 0 && 313 | (gradientColors[index].stop + toIncrease < maxStop(index))) { 314 | setState(() { 315 | gradientColors[index].stop += toIncrease; 316 | }); 317 | } else if (d.delta.dx < 0 && 318 | (gradientColors[index].stop - toIncrease > minStop(index))) { 319 | setState(() { 320 | gradientColors[index].stop -= toIncrease; 321 | }); 322 | } 323 | }, 324 | child: AnimatedContainer( 325 | duration: Duration(milliseconds: 200), 326 | margin: EdgeInsets.only( 327 | left: max * percent > width + padding 328 | ? max * percent - width - padding 329 | : max * percent), 330 | height: 50, 331 | width: width, 332 | decoration: BoxDecoration( 333 | color: gradientColors[index].color, 334 | borderRadius: BorderRadius.circular(50), 335 | border: Border.all( 336 | color: itemColor, width: currentColorIndex == index ? 4 : 2)), 337 | ), 338 | ); 339 | } 340 | 341 | Widget _degreesSlider() { 342 | return Container( 343 | width: 200, 344 | height: 200, 345 | child: SingleCircularSlider( 346 | 360, 347 | degreeValue.toInt(), 348 | onSelectionChange: (a, b, c) { 349 | if (b == 0) 350 | degreeValue = 1; 351 | else 352 | degreeValue = b.toDouble(); 353 | var alignmentTemp = 354 | GradientHelper.calcGradientAlignment(degreeValue); 355 | setState(() { 356 | begin = alignmentTemp.begin; 357 | end = alignmentTemp.end; 358 | }); 359 | }, 360 | child: Center( 361 | child: Text( 362 | '${degreeValue.floor()}°', 363 | style: TextStyle( 364 | fontWeight: FontWeight.bold, fontSize: 20, color: itemColor), 365 | )), 366 | )); 367 | } 368 | 369 | Widget _colorsList() { 370 | return Container( 371 | child: ReorderableWrap( 372 | alignment: WrapAlignment.center, 373 | onReorder: (int oldIndex, int newIndex) { 374 | onReorder(oldIndex, newIndex); 375 | }, 376 | children: [ 377 | ...gradientColors 378 | .map((e) => e.color) 379 | .toList() 380 | .asMap() 381 | .map((index, value) => MapEntry(index, __colorListItem(index))) 382 | .values 383 | .toList(), 384 | ]), 385 | ); 386 | } 387 | 388 | Widget __colorListItem(int index) { 389 | double width = 70; 390 | double height = width; 391 | return Container( 392 | width: width, 393 | height: height, 394 | child: Stack( 395 | children: [ 396 | InkWell( 397 | onTap: () { 398 | setState(() { 399 | currentColorIndex = index; 400 | }); 401 | }, 402 | child: Container( 403 | padding: currentColorIndex != index ? EdgeInsets.all(5) : null, 404 | child: Container( 405 | child: Card( 406 | elevation: 0, 407 | shape: RoundedRectangleBorder( 408 | borderRadius: BorderRadius.circular(10), 409 | side: BorderSide( 410 | color: itemColor, 411 | width: currentColorIndex == index ? 4 : 2)), 412 | color: gradientColors[index].color, 413 | child: Container( 414 | alignment: Alignment.center, 415 | child: Text( 416 | '${index + 1}', 417 | style: TextStyle( 418 | fontWeight: FontWeight.bold, color: itemColor), 419 | )), 420 | ), 421 | ), 422 | ), 423 | ), 424 | gradientColors.length <= 2 425 | ? Container() 426 | : Align( 427 | alignment: Alignment.topRight, 428 | child: Container( 429 | width: 20, 430 | height: 20, 431 | child: MaterialButton( 432 | onPressed: () { 433 | removeColor(index); 434 | }, 435 | shape: CircleBorder(), 436 | color: itemColor, 437 | padding: EdgeInsets.all(0), 438 | child: Icon( 439 | Icons.remove_circle, 440 | color: Colors.red, 441 | size: 20, 442 | ), 443 | ), 444 | ), 445 | ) 446 | ], 447 | ), 448 | ); 449 | } 450 | 451 | Widget _colorModifying() { 452 | if (currentColorIndex > gradientColors.length - 1) { 453 | currentColorIndex = gradientColors.length - 1; 454 | } 455 | return Container( 456 | child: SlidePicker( 457 | pickerColor: gradientColors[currentColorIndex].color, 458 | displayThumbColor: false, 459 | showLabel: false, 460 | showIndicator: false, 461 | sliderTextStyle: TextStyle(color: itemColor), 462 | onColorChanged: (newColor) { 463 | setState(() { 464 | gradientColors[currentColorIndex].color = newColor; 465 | }); 466 | }, 467 | ), 468 | ); 469 | } 470 | 471 | Widget _colorModifyingStopSlider() { 472 | return Container( 473 | width: MediaQuery.of(context).size.width * 0.7, 474 | child: Row( 475 | mainAxisAlignment: MainAxisAlignment.center, 476 | children: [ 477 | Text( 478 | 'STOP', 479 | style: TextStyle(fontWeight: FontWeight.bold, color: itemColor), 480 | ), 481 | Expanded( 482 | flex: 3, 483 | child: SliderTheme( 484 | data: SliderTheme.of(context).copyWith( 485 | activeTrackColor: gradientColors[currentColorIndex].color, 486 | inactiveTrackColor: 487 | gradientColors[currentColorIndex].color.withOpacity(0.5), 488 | trackShape: RoundedRectSliderTrackShape(), 489 | trackHeight: 7.0, 490 | thumbShape: RoundSliderThumbShape(enabledThumbRadius: 12.0), 491 | thumbColor: Colors.white, 492 | overlayColor: 493 | gradientColors[currentColorIndex].color.withOpacity(0.5), 494 | tickMarkShape: RoundSliderTickMarkShape(), 495 | activeTickMarkColor: gradientColors[currentColorIndex].color, 496 | inactiveTickMarkColor: gradientColors[currentColorIndex].color, 497 | valueIndicatorShape: PaddleSliderValueIndicatorShape(), 498 | valueIndicatorColor: gradientColors[currentColorIndex].color, 499 | ), 500 | child: Slider( 501 | value: gradientColors[currentColorIndex].stop, 502 | 503 | min: currentColorIndex == 0 504 | ? 0 505 | : (gradientColors[currentColorIndex - 1].stop + 0.01), 506 | max: currentColorIndex == gradientColors.length - 1 507 | ? 1 508 | : (gradientColors[currentColorIndex + 1].stop - 0.01), 509 | onChanged: (value) { 510 | setState(() { 511 | gradientColors[currentColorIndex].stop = value; 512 | }); 513 | }, 514 | // inactiveColor: PRIMARY_COLOR.withOpacity(0.01), 515 | // activeColor: PRIMARY_COLOR, 516 | ), 517 | ), 518 | ), 519 | Text( 520 | '${(gradientColors[currentColorIndex].stop * 100).toStringAsFixed(2)}%', 521 | textAlign: TextAlign.end, 522 | style: TextStyle(fontWeight: FontWeight.bold, color: itemColor), 523 | ) 524 | ], 525 | ), 526 | ); 527 | } 528 | 529 | Widget radialOption() { 530 | return Container( 531 | padding: EdgeInsets.only(bottom: 100), 532 | child: _linerOptionCard( 533 | Wrap( 534 | alignment: WrapAlignment.center, 535 | children: [ 536 | Container( 537 | margin: EdgeInsets.all(10), 538 | alignment: Alignment.center, 539 | child: Column( 540 | mainAxisSize: MainAxisSize.min, 541 | children: [ 542 | _stopViewer(), 543 | SizedBox( 544 | height: 30, 545 | ), 546 | _colorModifyingStopSlider(), 547 | ], 548 | ), 549 | ), 550 | SizedBox( 551 | height: 30, 552 | ), 553 | Container( 554 | margin: EdgeInsets.all(10), 555 | child: Column( 556 | children: [ 557 | Wrap( 558 | alignment: WrapAlignment.center, 559 | children: [_colorsList(), _addColorButton()], 560 | ), 561 | SizedBox( 562 | height: 30, 563 | ), 564 | _colorModifying() 565 | ], 566 | ), 567 | ), 568 | ], 569 | ), 570 | ), 571 | ); 572 | } 573 | 574 | Widget sweepOption() { 575 | return Container( 576 | padding: EdgeInsets.only(bottom: 100), 577 | child: _linerOptionCard( 578 | Column( 579 | mainAxisAlignment: MainAxisAlignment.center, 580 | children: [ 581 | _sweepEndSlider(), 582 | SizedBox( 583 | height: 30, 584 | ), 585 | Container( 586 | margin: EdgeInsets.all(10), 587 | alignment: Alignment.center, 588 | child: Column( 589 | mainAxisSize: MainAxisSize.min, 590 | children: [ 591 | _stopViewer(), 592 | SizedBox( 593 | height: 30, 594 | ), 595 | _colorModifyingStopSlider(), 596 | ], 597 | ), 598 | ), 599 | SizedBox( 600 | height: 30, 601 | ), 602 | Container( 603 | margin: EdgeInsets.all(10), 604 | child: Column( 605 | children: [ 606 | Wrap( 607 | alignment: WrapAlignment.center, 608 | children: [_colorsList(), _addColorButton()], 609 | ), 610 | SizedBox( 611 | height: 30, 612 | ), 613 | _colorModifying() 614 | ], 615 | ), 616 | ), 617 | ], 618 | ), 619 | ), 620 | ); 621 | } 622 | 623 | double sweepEndValue = pi / 180; 624 | 625 | Widget _sweepEndSlider() { 626 | return Container( 627 | child: IncreaseSlider( 628 | min: 1 * 2 * pi / 360, 629 | max: double.maxFinite, 630 | interval: pi / 180, 631 | onUpdate: (value) { 632 | if (value > pi / 180) 633 | setState(() { 634 | sweepEndValue = value; 635 | }); 636 | }, 637 | )); 638 | } 639 | 640 | //MAIN WIDGET 641 | @override 642 | void initState() { 643 | // TODO: implement initState 644 | super.initState(); 645 | for (var gradientColor in gradientColors) { 646 | gradientColor.color = _generateRandomColor(); 647 | } 648 | } 649 | 650 | @override 651 | Widget build(BuildContext context) { 652 | Gradient gradient = _type == 0 653 | ? LinearGradient( 654 | colors: [...gradientColors.map((e) => e.color).toList()], 655 | stops: [...gradientColors.map((e) => e.stop).toList()], 656 | begin: begin, 657 | end: end) 658 | : _type == 1 659 | ? RadialGradient( 660 | colors: [...gradientColors.map((e) => e.color).toList()], 661 | stops: [...gradientColors.map((e) => e.stop).toList()]) 662 | : SweepGradient( 663 | colors: [...gradientColors.map((e) => e.color).toList()], 664 | stops: [ 665 | ...gradientColors.map((e) => e.stop).toList(), 666 | ], 667 | center: FractionalOffset(0.5, 0.5), 668 | startAngle: 0, 669 | endAngle: sweepEndValue, 670 | ); 671 | return Scaffold( 672 | backgroundColor: gradientColors[0].color, 673 | // floatingActionButton: FloatingActionButton( 674 | // onPressed: () { 675 | // setState(() { 676 | // viewFull = !viewFull; 677 | // }); 678 | // }, 679 | // elevation: viewFull ? 0 : 10, 680 | // child: Container( 681 | // width: double.maxFinite, 682 | // height: double.maxFinite, 683 | // decoration: BoxDecoration( 684 | // border: Border.all(color: Colors.white, width: 3), 685 | // borderRadius: BorderRadius.circular(100), 686 | // gradient: gradient), 687 | // child: Icon(Icons.remove_red_eye)), 688 | // ), 689 | body: Stack( 690 | children: [ 691 | Container( 692 | // decoration: BoxDecoration( 693 | // image: DecorationImage( 694 | // image: AssetImage("assets/transparent.jpg"), 695 | // fit: BoxFit.fill)), 696 | child: AnimatedContainer( 697 | duration: Duration(milliseconds: 500), 698 | height: double.maxFinite, 699 | width: double.maxFinite, 700 | decoration: BoxDecoration( 701 | color: gradientColors[0].color, gradient: gradient), 702 | ), 703 | ), 704 | AnimatedSwitcher( 705 | duration: Duration(milliseconds: 500), 706 | child: viewFull 707 | ? SizedBox() 708 | : NoGrowScrollView( 709 | child: SingleChildScrollView( 710 | child: Wrap( 711 | alignment: WrapAlignment.center, 712 | children: [ 713 | SizedBox( 714 | height: 715 | MediaQuery.of(context).padding.top + 20, 716 | ), 717 | Container( 718 | padding: EdgeInsets.all(10), 719 | alignment: Alignment.center, 720 | child: Text( 721 | '#GRADiiENT', 722 | textAlign: TextAlign.center, 723 | style: TextStyle( 724 | fontSize: 30, 725 | fontWeight: FontWeight.bold, 726 | letterSpacing: 1.5, 727 | color: itemColor), 728 | ), 729 | ), 730 | typeSwitcher(), 731 | _type == 0 732 | ? linearOption() 733 | : _type == 1 734 | ? radialOption() 735 | : sweepOption(), 736 | SizedBox( 737 | height: 20, 738 | ) 739 | ], 740 | ), 741 | ), 742 | ), 743 | ), 744 | Align( 745 | alignment: Alignment.bottomCenter, 746 | child: Row( 747 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 748 | children: [ 749 | Container( 750 | margin: EdgeInsets.only(left: 10, bottom: 10), 751 | width: 50, 752 | height: 50, 753 | child: MaterialButton( 754 | onPressed: () { 755 | random(); 756 | }, 757 | child: Container( 758 | width: double.maxFinite, 759 | height: double.maxFinite, 760 | decoration: BoxDecoration( 761 | gradient: gradient, 762 | borderRadius: BorderRadius.circular(100), 763 | border: Border.all(color: itemColor, width: 2)), 764 | child: _randomLoading 765 | ? SpinKitDualRing( 766 | color: itemColor, 767 | duration: Duration(milliseconds: 500), 768 | ) 769 | : Icon( 770 | FontAwesomeIcons.dice, 771 | color: itemColor, 772 | ), 773 | ), 774 | padding: EdgeInsets.all(0), 775 | shape: CircleBorder(), 776 | ), 777 | ), 778 | Wrap( 779 | // mainAxisSize: MainAxisSize.min, 780 | alignment: WrapAlignment.center, 781 | children: [ 782 | Container( 783 | margin: EdgeInsets.only(right: 10, bottom: 10), 784 | width: 50, 785 | height: 50, 786 | child: MaterialButton( 787 | onPressed: () async { 788 | showSetWallpaperDialog(); 789 | }, 790 | child: Container( 791 | width: double.maxFinite, 792 | height: double.maxFinite, 793 | decoration: BoxDecoration( 794 | gradient: gradient, 795 | borderRadius: BorderRadius.circular(100), 796 | border: Border.all(color: itemColor, width: 2)), 797 | child: settingWallpaperDialogShowing 798 | ? SpinKitDualRing(color: itemColor) 799 | : Icon( 800 | FontAwesomeIcons.image, 801 | color: itemColor, 802 | ), 803 | ), 804 | padding: EdgeInsets.all(0), 805 | shape: CircleBorder(), 806 | ), 807 | ), 808 | // Container( 809 | // margin: EdgeInsets.only(right: 10, bottom: 10), 810 | // width: 50, 811 | // height: 50, 812 | // child: MaterialButton( 813 | // onPressed: () { 814 | // setState(() { 815 | // viewFull = !viewFull; 816 | // }); 817 | // }, 818 | // child: Container( 819 | // width: double.maxFinite, 820 | // height: double.maxFinite, 821 | // decoration: BoxDecoration( 822 | // gradient: gradient, 823 | // borderRadius: BorderRadius.circular(100), 824 | // border: Border.all(color: itemColor, width: 2)), 825 | // child: viewFull 826 | // ? SpinKitDualRing(color: itemColor) 827 | // : Icon( 828 | // FontAwesomeIcons.save, 829 | // color: itemColor, 830 | // ), 831 | // ), 832 | // padding: EdgeInsets.all(0), 833 | // shape: CircleBorder(), 834 | // ), 835 | // ), 836 | Container( 837 | margin: EdgeInsets.only(right: 10, bottom: 10), 838 | width: 50, 839 | height: 50, 840 | child: MaterialButton( 841 | onPressed: () { 842 | viewCode(); 843 | }, 844 | child: Container( 845 | width: double.maxFinite, 846 | height: double.maxFinite, 847 | decoration: BoxDecoration( 848 | gradient: gradient, 849 | borderRadius: BorderRadius.circular(100), 850 | border: Border.all(color: itemColor, width: 2)), 851 | child: Icon( 852 | FontAwesomeIcons.code, 853 | color: itemColor, 854 | ), 855 | ), 856 | padding: EdgeInsets.all(0), 857 | shape: CircleBorder(), 858 | ), 859 | ), 860 | Container( 861 | margin: EdgeInsets.only(right: 10, bottom: 10), 862 | width: 50, 863 | height: 50, 864 | child: MaterialButton( 865 | onPressed: () { 866 | setState(() { 867 | viewFull = !viewFull; 868 | }); 869 | }, 870 | child: Container( 871 | width: double.maxFinite, 872 | height: double.maxFinite, 873 | decoration: BoxDecoration( 874 | gradient: gradient, 875 | borderRadius: BorderRadius.circular(100), 876 | border: Border.all(color: itemColor, width: 2)), 877 | child: Icon( 878 | viewFull 879 | ? FontAwesomeIcons.slidersH 880 | : FontAwesomeIcons.eye, 881 | color: itemColor, 882 | ), 883 | ), 884 | padding: EdgeInsets.all(0), 885 | shape: CircleBorder(), 886 | ), 887 | ), 888 | ], 889 | ), 890 | ], 891 | ), 892 | ), 893 | ], 894 | )); 895 | } 896 | 897 | void onChangeStop() {} 898 | 899 | void random() { 900 | if (!_randomLoading) { 901 | int length = Random().nextInt(5 - 2 + 1) + 2; 902 | sweepEndValue = 903 | (Random().nextInt((360 * 2 * pi / 360 - pi / 180 + 1).floor()) + 904 | pi / 180) 905 | .toDouble(); 906 | List colors = 907 | List.generate(length, (index) => _generateRandomColor()); 908 | List stops = _impliedStops(length); 909 | gradientColors.clear(); 910 | for (int i = 0; i < colors.length; i++) { 911 | gradientColors 912 | .add(AnKiiGradientColor(stop: stops[i], color: colors[i])); 913 | } 914 | degreeValue = Random().nextInt(360).toDouble(); 915 | var alignment = 916 | GradientHelper.calcGradientAlignment(degreeValue.toDouble()); 917 | setState(() { 918 | begin = alignment.begin; 919 | end = alignment.end; 920 | currentColorIndex = gradientColors.length - 1; 921 | }); 922 | 923 | if (!viewFull) { 924 | setState(() { 925 | _randomLoading = true; 926 | viewFull = true; 927 | }); 928 | 929 | Future.delayed(Duration(milliseconds: 500), () { 930 | setState(() { 931 | _randomLoading = false; 932 | viewFull = false; 933 | }); 934 | }); 935 | } 936 | } 937 | } 938 | 939 | void removeColor(int index) { 940 | setState(() { 941 | gradientColors.removeAt(index); 942 | gradientColors.last.stop = 1; 943 | currentColorIndex = gradientColors.length - 1; 944 | }); 945 | } 946 | 947 | void addColor() { 948 | List stops = _impliedStops(gradientColors.length); 949 | 950 | // gradientColors.map((e) => e.stop).followedBy(stops); 951 | setState(() { 952 | // gradientColors.last.stop = 953 | // (1 + gradientColors[gradientColors.length - 2].stop) / 2; 954 | gradientColors 955 | .add(AnKiiGradientColor(stop: 1, color: _generateRandomColor())); 956 | var stops = _impliedStops(gradientColors.length); 957 | gradientColors.asMap().forEach((index, value) { 958 | value.stop = stops[index]; 959 | }); 960 | 961 | currentColorIndex = gradientColors.length - 1; 962 | }); 963 | } 964 | 965 | onReorder(int oldIndex, int newIndex) { 966 | print('$oldIndex - $newIndex'); 967 | var oldTempColor = gradientColors[oldIndex].color; 968 | var newTempColor = gradientColors[newIndex].color; 969 | gradientColors[oldIndex].color = newTempColor; 970 | gradientColors[newIndex].color = oldTempColor; 971 | setState(() { 972 | currentColorIndex = newIndex; 973 | }); 974 | } 975 | 976 | void viewCode() { 977 | bool copied = false; 978 | int codeTypeIndex = 0; 979 | showDialog( 980 | context: context, 981 | builder: (_) => AlertDialog( 982 | content: StatefulBuilder(builder: (context, stateSetter) { 983 | var html = genCode( 984 | gradientType: 985 | _type == 0 ? GradientType.linear : GradientType.radial, 986 | codeType: codeTypeIndex == 0 987 | ? CodeGenType.flutter 988 | : codeTypeIndex == 1 989 | ? CodeGenType.css 990 | : codeTypeIndex == 2 991 | ? CodeGenType.android 992 | : codeTypeIndex == 3 993 | ? CodeGenType.ios 994 | : CodeGenType.reactNative); 995 | var result = html.withOutHtmlTag(); 996 | return Container( 997 | child: SingleChildScrollView( 998 | child: Column( 999 | mainAxisSize: MainAxisSize.min, 1000 | children: [ 1001 | NoGrowScrollView( 1002 | child: SingleChildScrollView( 1003 | scrollDirection: Axis.horizontal, 1004 | child: Row( 1005 | children: [ 1006 | __viewCodeButton( 1007 | onPressed: () { 1008 | stateSetter(() { 1009 | codeTypeIndex = 0; 1010 | }); 1011 | }, 1012 | selected: codeTypeIndex == 0, 1013 | text: 'Flutter'), 1014 | __viewCodeButton( 1015 | onPressed: () { 1016 | stateSetter(() { 1017 | codeTypeIndex = 1; 1018 | }); 1019 | }, 1020 | selected: codeTypeIndex == 1, 1021 | text: 'CSS'), 1022 | __viewCodeButton( 1023 | onPressed: () { 1024 | stateSetter(() { 1025 | codeTypeIndex = 2; 1026 | }); 1027 | }, 1028 | selected: codeTypeIndex == 2, 1029 | text: 'Android'), 1030 | __viewCodeButton( 1031 | onPressed: () { 1032 | stateSetter(() { 1033 | codeTypeIndex = 3; 1034 | }); 1035 | }, 1036 | selected: codeTypeIndex == 3, 1037 | text: 'iOS'), 1038 | __viewCodeButton( 1039 | onPressed: () { 1040 | stateSetter(() { 1041 | codeTypeIndex = 4; 1042 | }); 1043 | }, 1044 | selected: codeTypeIndex == 4, 1045 | text: 'React Native') 1046 | ], 1047 | ), 1048 | ), 1049 | ), 1050 | Html( 1051 | data: html, 1052 | style: { 1053 | "h2": Style(color: Colors.cyan), 1054 | "em": Style(color: Colors.lightBlue) 1055 | }, 1056 | ), 1057 | Row( 1058 | mainAxisAlignment: MainAxisAlignment.spaceAround, 1059 | children: [ 1060 | copied 1061 | ? Column( 1062 | children: [ 1063 | Icon( 1064 | FontAwesomeIcons.check, 1065 | color: Colors.green, 1066 | size: 20, 1067 | ), 1068 | Text( 1069 | 'Copied!', 1070 | style: TextStyle(color: Colors.green), 1071 | ) 1072 | ], 1073 | ) 1074 | : IconButton( 1075 | icon: Icon(FontAwesomeIcons.copy), 1076 | onPressed: () async { 1077 | await Clipboard.setData( 1078 | ClipboardData(text: result)); 1079 | stateSetter(() { 1080 | copied = true; 1081 | }); 1082 | }), 1083 | IconButton( 1084 | icon: Icon(FontAwesomeIcons.shareAlt), 1085 | onPressed: () { 1086 | Share.share(result); 1087 | }), 1088 | ]) 1089 | ], 1090 | ), 1091 | ), 1092 | ); 1093 | }), 1094 | )); 1095 | } 1096 | 1097 | Widget __viewCodeButton( 1098 | {Function onPressed, bool selected = false, @required String text}) { 1099 | return FlatButton( 1100 | onPressed: () { 1101 | onPressed?.call(); 1102 | }, 1103 | child: Text( 1104 | '$text', 1105 | style: TextStyle( 1106 | fontWeight: selected ? FontWeight.bold : null, 1107 | color: selected ? gradientColors[0].color : Colors.black26), 1108 | ), 1109 | ); 1110 | } 1111 | 1112 | bool settingWallpaperDialogShowing = false; 1113 | bool setHomeWallpaper = true; 1114 | bool setLockWallpaper = true; 1115 | bool saveImage = true; 1116 | 1117 | showSetWallpaperDialog() async { 1118 | // bool settingWallpaper = false; 1119 | // bool isSuccessfully; 1120 | // setState(() { 1121 | // settingWallpaperDialogShowing = true; 1122 | // }); 1123 | // await showDialog( 1124 | // context: context, 1125 | // barrierDismissible: false, 1126 | // builder:(_)=> AlertDialog( 1127 | // title: Text('Set Wallpaper'), 1128 | // content: StatefulBuilder(builder: (context, stateSetter) { 1129 | // return Container( 1130 | // child: isSuccessfully != null 1131 | // ? Icon( 1132 | // FontAwesomeIcons.check, 1133 | // color: Colors.green, 1134 | // size: 50, 1135 | // ) 1136 | // : settingWallpaper 1137 | // ? Container( 1138 | // width: 100, 1139 | // height: 100, 1140 | // child: 1141 | // SpinKitDualRing(color: gradientColors[0].color)) 1142 | // : SingleChildScrollView( 1143 | // child: Column( 1144 | // children: [ 1145 | // Row( 1146 | // children: [ 1147 | // Checkbox( 1148 | // value: saveImage, 1149 | // activeColor: gradientColors[0].color, 1150 | // onChanged: (value) { 1151 | // stateSetter(() { 1152 | // saveImage = value; 1153 | // }); 1154 | // }), 1155 | // Expanded( 1156 | // child: Text( 1157 | // 'Save image${saveImage ? '\n(0/GRADiiENT/Wallpapers/)' : ''}')) 1158 | // ], 1159 | // ), 1160 | // Row( 1161 | // children: [ 1162 | // Checkbox( 1163 | // value: setHomeWallpaper, 1164 | // activeColor: gradientColors[0].color, 1165 | // onChanged: (value) { 1166 | // stateSetter(() { 1167 | // setHomeWallpaper = value; 1168 | // }); 1169 | // }), 1170 | // Expanded( 1171 | // child: 1172 | // Text('Set as Home Screen Wallpaper')) 1173 | // ], 1174 | // ), 1175 | // Row( 1176 | // children: [ 1177 | // Checkbox( 1178 | // value: setLockWallpaper, 1179 | // activeColor: gradientColors[0].color, 1180 | // onChanged: (value) { 1181 | // stateSetter(() { 1182 | // setLockWallpaper = value; 1183 | // }); 1184 | // }), 1185 | // Expanded( 1186 | // child: 1187 | // Text('Set as Lock Screen Wallpaper')) 1188 | // ], 1189 | // ), 1190 | // SizedBox( 1191 | // height: 20, 1192 | // ), 1193 | // Row( 1194 | // mainAxisAlignment: MainAxisAlignment.center, 1195 | // crossAxisAlignment: CrossAxisAlignment.center, 1196 | // children: [ 1197 | // !setHomeWallpaper && !setLockWallpaper 1198 | // ? Container() 1199 | // : FlatButton( 1200 | // child: Text( 1201 | // 'Set', 1202 | // style: TextStyle( 1203 | // fontWeight: FontWeight.bold, 1204 | // color: gradientColors[0].color, 1205 | // fontSize: 20), 1206 | // ), 1207 | // onPressed: () async { 1208 | // stateSetter(() { 1209 | // settingWallpaper = true; 1210 | // }); 1211 | // await _setWallpaper( 1212 | // homeScreen: setHomeWallpaper, 1213 | // lockScreen: setLockWallpaper, 1214 | // save: saveImage); 1215 | // stateSetter(() { 1216 | // isSuccessfully = true; 1217 | // }); 1218 | // Future.delayed(Duration(seconds: 2), 1219 | // () { 1220 | // stateSetter(() { 1221 | // Navigator.pop(context); 1222 | // }); 1223 | // }); 1224 | // }, 1225 | // ), 1226 | // FlatButton( 1227 | // child: Text('Close'), 1228 | // onPressed: () { 1229 | // Navigator.pop(context); 1230 | // }, 1231 | // ) 1232 | // ], 1233 | // ) 1234 | // ], 1235 | // ), 1236 | // ), 1237 | // ); 1238 | // }), 1239 | // )); 1240 | // setState(() { 1241 | // settingWallpaperDialogShowing = false; 1242 | // }); 1243 | } 1244 | 1245 | _setWallpaper( 1246 | {bool save = true, 1247 | bool homeScreen = true, 1248 | bool lockScreen = true}) async { 1249 | // //GRADIENT 1250 | // Gradient gradient = _type == 0 1251 | // ? LinearGradient( 1252 | // colors: [...gradientColors.map((e) => e.color).toList()], 1253 | // stops: [...gradientColors.map((e) => e.stop).toList()], 1254 | // begin: begin, 1255 | // end: end) 1256 | // : RadialGradient( 1257 | // colors: [...gradientColors.map((e) => e.color).toList()], 1258 | // stops: [...gradientColors.map((e) => e.stop).toList()]); 1259 | 1260 | // // IMAGE SIZE 1261 | // double imageWidth = 2160; 1262 | // double imageHeight = 3840; 1263 | 1264 | // //DRAW WITH CANVAS 1265 | // ui.PictureRecorder pictureRecorder = ui.PictureRecorder(); 1266 | // Canvas canvas = Canvas(pictureRecorder); 1267 | // Paint paint = Paint(); 1268 | // paint.shader = gradient.createShader(Rect.fromCenter( 1269 | // center: Offset(imageWidth / 2, imageHeight / 2), 1270 | // width: imageWidth, 1271 | // height: imageHeight)); 1272 | // canvas.drawRect( 1273 | // Rect.fromCenter( 1274 | // center: Offset(imageWidth / 2, imageHeight / 2), 1275 | // width: imageWidth, 1276 | // height: imageHeight), 1277 | // paint); 1278 | 1279 | // ui.Image image = await pictureRecorder 1280 | // .endRecording() 1281 | // .toImage(imageWidth.floor(), imageHeight.floor()); 1282 | 1283 | // //SAVE 1284 | // String fileName = 1285 | // (DateTime.now()).toIso8601String().replaceAll(".", "") + ".png"; 1286 | // // "${gradient.colors.map((e) => e.value).toList()}_${gradient.stops.map((e) => e.toStringAsFixed(2)).toList()}_${begin}_${end}.png"; 1287 | // var resultPath = await WallpaperService.save( 1288 | // (await image.toByteData(format: ui.ImageByteFormat.png)), 1289 | // fileName: fileName); 1290 | // // SET WALLPAPER 1291 | // int setWallpaperFor = homeScreen && lockScreen 1292 | // ? WallpaperManager.BOTH_SCREENS 1293 | // : homeScreen && !lockScreen 1294 | // ? WallpaperManager.HOME_SCREEN 1295 | // : WallpaperManager.LOCK_SCREEN; 1296 | // await WallpaperManager.setWallpaperFromFile(resultPath, setWallpaperFor); 1297 | // File tempFile = File(resultPath); 1298 | // if (save) { 1299 | // await __saveWallpaper(tempFile, fileName); 1300 | // } 1301 | // //delete temp file 1302 | // await tempFile.delete(recursive: true); 1303 | } 1304 | 1305 | __saveWallpaper(File file, String fileName) async { 1306 | var permission = Permission.storage; 1307 | var permissionStatus = await permission.status; 1308 | if (permissionStatus.isGranted) { 1309 | Directory directory = 1310 | Directory("/storage/emulated/0/GRADiiEnt/Wallpapers/"); 1311 | if (!(await directory.exists())) { 1312 | await directory.create(recursive: true); 1313 | } 1314 | (await file.copy(directory.path + fileName)).create(); 1315 | return; 1316 | } else if (permissionStatus.isPermanentlyDenied) { 1317 | //HANDLE PERMANENTLY; 1318 | } else { 1319 | await permission.request(); 1320 | permissionStatus = await permission.status; 1321 | if (permissionStatus.isGranted) { 1322 | Directory directory = 1323 | Directory("/storage/emulated/0/GRADiiEnt/Wallpapers/"); 1324 | if (!(await directory.exists())) { 1325 | await directory.create(recursive: true); 1326 | } 1327 | (await file.copy(directory.path + fileName)).create(); 1328 | return; 1329 | } 1330 | } 1331 | } 1332 | 1333 | List _impliedStops(int length) { 1334 | final double separation = 1.0 / (length - 1); 1335 | return List.generate( 1336 | length, 1337 | (int index) => index * separation, 1338 | growable: false, 1339 | ); 1340 | } 1341 | 1342 | double maxStop(int index) { 1343 | // min: currentColorIndex == 0 1344 | // ? 0 1345 | // : (gradientColors[currentColorIndex - 1].stop + 0.01), 1346 | double max = index == gradientColors.length - 1 1347 | ? 1 1348 | : (gradientColors[index + 1].stop - 0.01); 1349 | return max; 1350 | } 1351 | 1352 | double minStop(int index) { 1353 | double min = index == 0 ? 0 : (gradientColors[index - 1].stop + 0.01); 1354 | return min; 1355 | } 1356 | 1357 | double genWidth(int index, {@required double maxWidth}) { 1358 | double toSubtract = 0; 1359 | for (int i = 0; i < index; i++) { 1360 | toSubtract += gradientColors[i].stop * maxWidth; 1361 | } 1362 | for (int i = index + 1; i < gradientColors.length; i++) { 1363 | toSubtract += gradientColors[i].stop * maxWidth; 1364 | } 1365 | print(toSubtract); 1366 | return maxWidth - toSubtract; 1367 | } 1368 | 1369 | Color _generateRandomColor() { 1370 | return Color.fromRGBO( 1371 | Random().nextInt(250), Random().nextInt(250), Random().nextInt(250), 1); 1372 | } 1373 | 1374 | String genCode( 1375 | {CodeGenType codeType = CodeGenType.flutter, 1376 | GradientType gradientType = GradientType.linear}) { 1377 | String flutterLinearResult = "

LinearGradient

(" 1378 | "

colors: ${gradientColors.map((e) => e.color).toList()}," 1379 | "

stops: ${gradientColors.map((e) => e.stop).toList()}," 1380 | "

begin: $begin," 1381 | "

end: $end" 1382 | "

)

"; 1383 | String flutterRadialResult = "

RadialGradient

(" 1384 | "

colors: ${gradientColors.map((e) => e.color).toList()}," 1385 | "

stops: ${gradientColors.map((e) => e.stop).toList()}," 1386 | "

)

"; 1387 | 1388 | //CSS 1389 | var colorsString = ""; 1390 | gradientColors.forEach((element) { 1391 | colorsString += 1392 | "

rgba(${element.color.red},${element.color.green},${element.color.blue},${element.color.opacity}) ${element.stop * 100}%, "; 1393 | }); 1394 | String cssResultLinear = 1395 | "

background: rgb(${gradientColors[0].color.red},${gradientColors[0].color.green},${gradientColors[0].color.blue});" 1396 | "

background: linear-gradient

(${degreeValue}deg, " 1397 | "${colorsString});"; 1398 | String cssResultRadial = 1399 | "

background: rgb(${gradientColors[0].color.red},${gradientColors[0].color.green},${gradientColors[0].color.blue});" 1400 | "

background:radial-gradient

(circle, " 1401 | "${colorsString});"; 1402 | if (gradientType == GradientType.linear) { 1403 | if (codeType == CodeGenType.flutter) { 1404 | return flutterLinearResult; 1405 | } 1406 | if (codeType == CodeGenType.css) { 1407 | return cssResultLinear; 1408 | } 1409 | if (codeType == CodeGenType.android) { 1410 | return "(っ◔◡◔)っ ♥ Updating ♥"; 1411 | } 1412 | if (codeType == CodeGenType.ios) { 1413 | return "(っ◔◡◔)っ ♥ Updating ♥"; 1414 | } 1415 | if (codeType == CodeGenType.reactNative) { 1416 | return "(っ◔◡◔)っ ♥ Updating ♥"; 1417 | } 1418 | } else { 1419 | if (codeType == CodeGenType.flutter) { 1420 | return flutterRadialResult; 1421 | } 1422 | if (codeType == CodeGenType.css) { 1423 | return cssResultRadial; 1424 | } 1425 | if (codeType == CodeGenType.android) { 1426 | return "(っ◔◡◔)っ ♥ Updating ♥"; 1427 | } 1428 | if (codeType == CodeGenType.ios) { 1429 | return "(っ◔◡◔)っ ♥ Updating ♥"; 1430 | } 1431 | if (codeType == CodeGenType.reactNative) { 1432 | return "(っ◔◡◔)っ ♥ Updating ♥"; 1433 | } 1434 | } 1435 | return flutterLinearResult; 1436 | } 1437 | } 1438 | 1439 | enum CodeGenType { 1440 | flutter, 1441 | css, 1442 | android, 1443 | ios, 1444 | reactNative, 1445 | } 1446 | enum GradientType { linear, radial } 1447 | 1448 | class AnKiiGradientColor { 1449 | double stop; 1450 | Color color; 1451 | 1452 | AnKiiGradientColor({@required this.stop, @required this.color}); 1453 | } 1454 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/services/wallpaper_service.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:typed_data'; 3 | import 'dart:ui' as ui; 4 | import 'package:flutter/cupertino.dart'; 5 | import 'package:flutter/rendering.dart'; 6 | import 'package:path_provider/path_provider.dart'; 7 | 8 | //ANDROID ONLY 9 | const String wallpaperPath = "/GradientWallpapers"; 10 | 11 | class WallpaperService { 12 | static Future createPng(GlobalKey globalKey) async { 13 | // RenderObject? boundary = 14 | // globalKey.currentContext?.findRenderObject(); 15 | // ui.Image image = await ((RenderRepaintBoundary)boundary!).toImage(); 16 | // ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png); 17 | // Uint8List pngBytes = byteData.buffer.asUint8List(); 18 | // return pngBytes; 19 | return Uint8List(0); 20 | } 21 | 22 | static Future save(ByteData byteData, 23 | {String fileName = "ankiimation.png"}) async { 24 | // var rootPath = await getExternalStorageDirectory(); 25 | // String fullPath = rootPath.path + wallpaperPath + "/" + fileName; 26 | // await Directory(rootPath.path + wallpaperPath).create(); 27 | // File file = await File(fullPath).create(); 28 | // await file.writeAsBytes(byteData.buffer.asUint8List()); 29 | // return file.path; 30 | return ''; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/widgets/circular_slider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:math'; 2 | import 'package:flutter/gestures.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | //TODO: this widget copy and modifying from https://github.com/davidanaya/flutter-circular-slider 6 | //TODO: Thank you so much. Contact me if i'm wrong to do that: ankiimation@gmail.com ;) 7 | /// Returns a widget which displays a circle to be used as a slider. 8 | /// 9 | /// Required arguments are position and divisions to set the initial selection. 10 | /// onSelectionChange is a callback function which returns new values as the user 11 | /// changes the interval. 12 | /// The rest of the params are used to change the look and feel. 13 | /// 14 | /// SingleCircularSlider(5, 10, onSelectionChange: () => {}); 15 | class SingleCircularSlider extends StatefulWidget { 16 | /// the selection will be values between 0..divisions; max value is 300 17 | final int divisions; 18 | 19 | /// the initial value in the selection 20 | final int position; 21 | 22 | /// the number of primary sectors to be painted 23 | /// will be painted using selectionColor 24 | final int primarySectors; 25 | 26 | /// the number of secondary sectors to be painted 27 | /// will be painted using baseColor 28 | final int secondarySectors; 29 | 30 | /// an optional widget that would be mounted inside the circle 31 | final Widget child; 32 | 33 | /// height of the canvas, default at 220 34 | final double height; 35 | 36 | /// width of the canvas, default at 220 37 | final double width; 38 | 39 | /// color of the base circle and sections 40 | final Color baseColor; 41 | 42 | /// color of the selection 43 | final Color selectionColor; 44 | 45 | /// color of the handlers 46 | final Color handlerColor; 47 | 48 | /// callback function when init and end change 49 | /// (int init, int end) => void 50 | final SelectionChanged onSelectionChange; 51 | 52 | /// callback function when init and end finish 53 | /// (int init, int end) => void 54 | final SelectionChanged onSelectionEnd; 55 | 56 | /// outter radius for the handlers 57 | final double handlerOutterRadius; 58 | 59 | /// if true will paint a rounded cap in the selection slider start 60 | final bool showRoundedCapInSelection; 61 | 62 | /// if true an extra handler ring will be displayed in the handler 63 | final bool showHandlerOutter; 64 | 65 | /// stroke width for the slider, defaults at 12.0 66 | final double sliderStrokeWidth; 67 | 68 | /// if true, the onSelectionChange will also return the number of laps in the slider 69 | /// otherwise, everytime the user completes a full lap, the selection restarts from 0 70 | final bool shouldCountLaps; 71 | 72 | SingleCircularSlider( 73 | this.divisions, 74 | this.position, { 75 | this.height, 76 | this.width, 77 | this.child, 78 | this.primarySectors, 79 | this.secondarySectors, 80 | this.baseColor, 81 | this.selectionColor, 82 | this.handlerColor, 83 | this.onSelectionChange, 84 | this.onSelectionEnd, 85 | this.handlerOutterRadius, 86 | this.showRoundedCapInSelection, 87 | this.showHandlerOutter, 88 | this.sliderStrokeWidth, 89 | this.shouldCountLaps, 90 | }) : assert(position >= 0 && position <= divisions, 91 | 'init has to be > 0 and < divisions value'), 92 | assert(divisions >= 0, 'divisions has to be > 0 and <= 300'); 93 | 94 | @override 95 | _SingleCircularSliderState createState() => _SingleCircularSliderState(); 96 | } 97 | 98 | class _SingleCircularSliderState extends State { 99 | int _end; 100 | 101 | @override 102 | void initState() { 103 | super.initState(); 104 | _end = widget.position; 105 | } 106 | 107 | @override 108 | Widget build(BuildContext context) { 109 | return Container( 110 | height: widget.height ?? 220, 111 | width: widget.width ?? 220, 112 | child: CircularSliderPaint( 113 | mode: CircularSliderMode.singleHandler, 114 | init: 0, 115 | end: _end, 116 | divisions: widget.divisions, 117 | primarySectors: widget.primarySectors ?? 0, 118 | secondarySectors: widget.secondarySectors ?? 0, 119 | child: widget.child, 120 | onSelectionChange: (newInit, newEnd, laps) { 121 | if (widget.onSelectionChange != null) { 122 | widget.onSelectionChange(newInit, newEnd, laps); 123 | } 124 | setState(() { 125 | _end = newEnd; 126 | }); 127 | }, 128 | onSelectionEnd: (newInit, newEnd, laps) { 129 | if (widget.onSelectionEnd != null) { 130 | widget.onSelectionEnd(newInit, newEnd, laps); 131 | } 132 | }, 133 | sliderStrokeWidth: widget.sliderStrokeWidth ?? 12.0, 134 | baseColor: widget.baseColor ?? Color.fromRGBO(255, 255, 255, 0.1), 135 | selectionColor: 136 | widget.selectionColor ?? Color.fromRGBO(255, 255, 255, 0.3), 137 | handlerColor: widget.handlerColor ?? Colors.white, 138 | handlerOutterRadius: widget.handlerOutterRadius ?? 12.0, 139 | showRoundedCapInSelection: widget.showRoundedCapInSelection ?? false, 140 | showHandlerOutter: widget.showHandlerOutter ?? true, 141 | shouldCountLaps: widget.shouldCountLaps ?? false, 142 | )); 143 | } 144 | } 145 | 146 | enum CircularSliderMode { singleHandler, doubleHandler } 147 | 148 | enum SlidingState { none, endIsBiggerThanStart, endIsSmallerThanStart } 149 | 150 | typedef SelectionChanged = void Function(T a, T b, T c); 151 | 152 | class CircularSliderPaint extends StatefulWidget { 153 | final CircularSliderMode mode; 154 | final int init; 155 | final int end; 156 | final int divisions; 157 | final int primarySectors; 158 | final int secondarySectors; 159 | final SelectionChanged onSelectionChange; 160 | final SelectionChanged onSelectionEnd; 161 | final Color baseColor; 162 | final Color selectionColor; 163 | final Color handlerColor; 164 | final double handlerOutterRadius; 165 | final Widget child; 166 | final bool showRoundedCapInSelection; 167 | final bool showHandlerOutter; 168 | final double sliderStrokeWidth; 169 | final bool shouldCountLaps; 170 | 171 | CircularSliderPaint({ 172 | @required this.mode, 173 | @required this.divisions, 174 | @required this.init, 175 | @required this.end, 176 | this.child, 177 | @required this.primarySectors, 178 | @required this.secondarySectors, 179 | @required this.onSelectionChange, 180 | @required this.onSelectionEnd, 181 | @required this.baseColor, 182 | @required this.selectionColor, 183 | @required this.handlerColor, 184 | @required this.handlerOutterRadius, 185 | @required this.showRoundedCapInSelection, 186 | @required this.showHandlerOutter, 187 | @required this.sliderStrokeWidth, 188 | @required this.shouldCountLaps, 189 | }); 190 | 191 | @override 192 | _CircularSliderState createState() => _CircularSliderState(); 193 | } 194 | 195 | class _CircularSliderState extends State { 196 | bool _isInitHandlerSelected = false; 197 | bool _isEndHandlerSelected = false; 198 | 199 | SliderPainter _painter; 200 | 201 | /// start angle in radians where we need to locate the init handler 202 | double _startAngle; 203 | 204 | /// end angle in radians where we need to locate the end handler 205 | double _endAngle; 206 | 207 | /// the absolute angle in radians representing the selection 208 | double _sweepAngle; 209 | 210 | /// in case we have a double slider and we want to move the whole selection by clicking in the slider 211 | /// this will capture the position in the selection relative to the initial handler 212 | /// that way we will be able to keep the selection constant when moving 213 | int _differenceFromInitPoint; 214 | 215 | /// will store the number of full laps (2pi radians) as part of the selection 216 | int _laps = 0; 217 | 218 | /// will be used to calculate in the next movement if we need to increase or decrease _laps 219 | SlidingState _slidingState = SlidingState.none; 220 | 221 | bool get isDoubleHandler => widget.mode == CircularSliderMode.doubleHandler; 222 | 223 | bool get isSingleHandler => widget.mode == CircularSliderMode.singleHandler; 224 | 225 | bool get isBothHandlersSelected => 226 | _isEndHandlerSelected && _isInitHandlerSelected; 227 | 228 | bool get isNoHandlersSelected => 229 | !_isEndHandlerSelected && !_isInitHandlerSelected; 230 | 231 | @override 232 | void initState() { 233 | super.initState(); 234 | _calculatePaintData(); 235 | } 236 | 237 | // we need to update this widget both with gesture detector but 238 | // also when the parent widget rebuilds itself 239 | @override 240 | void didUpdateWidget(CircularSliderPaint oldWidget) { 241 | super.didUpdateWidget(oldWidget); 242 | if (oldWidget.init != widget.init || oldWidget.end != widget.end) { 243 | _calculatePaintData(); 244 | } 245 | } 246 | 247 | @override 248 | Widget build(BuildContext context) { 249 | return RawGestureDetector( 250 | gestures: { 251 | CustomPanGestureRecognizer: 252 | GestureRecognizerFactoryWithHandlers( 253 | () => CustomPanGestureRecognizer( 254 | onPanDown: _onPanDown, 255 | onPanUpdate: _onPanUpdate, 256 | onPanEnd: _onPanEnd, 257 | ), 258 | (CustomPanGestureRecognizer instance) {}, 259 | ), 260 | }, 261 | child: CustomPaint( 262 | painter: BasePainter( 263 | baseColor: widget.baseColor, 264 | selectionColor: widget.selectionColor, 265 | primarySectors: widget.primarySectors, 266 | secondarySectors: widget.secondarySectors, 267 | sliderStrokeWidth: widget.sliderStrokeWidth, 268 | ), 269 | foregroundPainter: _painter, 270 | child: Padding( 271 | padding: const EdgeInsets.all(12.0), 272 | child: widget.child, 273 | ), 274 | ), 275 | ); 276 | } 277 | 278 | void _calculatePaintData() { 279 | var initPercent = isDoubleHandler 280 | ? _valueToPercentage(widget.init, widget.divisions) 281 | : 0.0; 282 | var endPercent = _valueToPercentage(widget.end, widget.divisions); 283 | var sweep = _getSweepAngle(initPercent, endPercent); 284 | 285 | var previousStartAngle = _startAngle; 286 | var previousEndAngle = _endAngle; 287 | 288 | _startAngle = isDoubleHandler ? _percentageToRadians(initPercent) : 0.0; 289 | _endAngle = _percentageToRadians(endPercent); 290 | _sweepAngle = _percentageToRadians(sweep.abs()); 291 | 292 | // update full laps if need be 293 | if (widget.shouldCountLaps) { 294 | var newSlidingState = _calculateSlidingState(_startAngle, _endAngle); 295 | if (isSingleHandler) { 296 | _laps = _calculateLapsForsSingleHandler( 297 | _endAngle, previousEndAngle, _slidingState, _laps); 298 | _slidingState = newSlidingState; 299 | } else { 300 | // is double handler 301 | if (newSlidingState != _slidingState) { 302 | _laps = _calculateLapsForDoubleHandler( 303 | _startAngle, 304 | _endAngle, 305 | previousStartAngle, 306 | previousEndAngle, 307 | _slidingState, 308 | newSlidingState, 309 | _laps); 310 | _slidingState = newSlidingState; 311 | } 312 | } 313 | } 314 | 315 | _painter = SliderPainter( 316 | mode: widget.mode, 317 | startAngle: _startAngle, 318 | endAngle: _endAngle, 319 | sweepAngle: _sweepAngle, 320 | selectionColor: widget.selectionColor, 321 | handlerColor: widget.handlerColor, 322 | handlerOutterRadius: widget.handlerOutterRadius, 323 | showRoundedCapInSelection: widget.showRoundedCapInSelection, 324 | showHandlerOutter: widget.showHandlerOutter, 325 | sliderStrokeWidth: widget.sliderStrokeWidth, 326 | ); 327 | } 328 | 329 | int _calculateLapsForsSingleHandler( 330 | double end, double prevEnd, SlidingState slidingState, int laps) { 331 | if (slidingState != SlidingState.none) { 332 | if (_radiansWasModuloed(end, prevEnd)) { 333 | var lapIncrement = end < prevEnd ? 1 : -1; 334 | var newLaps = laps + lapIncrement; 335 | return newLaps < 0 ? 0 : newLaps; 336 | } 337 | } 338 | return laps; 339 | } 340 | 341 | int _calculateLapsForDoubleHandler( 342 | double start, 343 | double end, 344 | double prevStart, 345 | double prevEnd, 346 | SlidingState slidingState, 347 | SlidingState newSlidingState, 348 | int laps) { 349 | if (slidingState != SlidingState.none) { 350 | if (!_radiansWasModuloed(start, prevStart) && 351 | !_radiansWasModuloed(end, prevEnd)) { 352 | var lapIncrement = 353 | newSlidingState == SlidingState.endIsBiggerThanStart ? 1 : -1; 354 | var newLaps = laps + lapIncrement; 355 | return newLaps < 0 ? 0 : newLaps; 356 | } 357 | } 358 | return laps; 359 | } 360 | 361 | SlidingState _calculateSlidingState(double start, double end) { 362 | return end > start 363 | ? SlidingState.endIsBiggerThanStart 364 | : SlidingState.endIsSmallerThanStart; 365 | } 366 | 367 | void _onPanUpdate(Offset details) { 368 | if (!_isInitHandlerSelected && !_isEndHandlerSelected) { 369 | return; 370 | } 371 | if (_painter.center == null) { 372 | return; 373 | } 374 | _handlePan(details, false); 375 | } 376 | 377 | void _onPanEnd(Offset details) { 378 | _handlePan(details, true); 379 | 380 | _isInitHandlerSelected = false; 381 | _isEndHandlerSelected = false; 382 | } 383 | 384 | void _handlePan(Offset details, bool isPanEnd) { 385 | RenderBox renderBox = context.findRenderObject(); 386 | var position = renderBox.globalToLocal(details); 387 | 388 | var angle = _coordinatesToRadians(_painter.center, position); 389 | var percentage = _radiansToPercentage(angle); 390 | var newValue = _percentageToValue(percentage, widget.divisions); 391 | 392 | if (isBothHandlersSelected) { 393 | var newValueInit = 394 | (newValue - _differenceFromInitPoint) % widget.divisions; 395 | if (newValueInit != widget.init) { 396 | var newValueEnd = 397 | (widget.end + (newValueInit - widget.init)) % widget.divisions; 398 | widget.onSelectionChange(newValueInit, newValueEnd, _laps); 399 | if (isPanEnd) { 400 | widget.onSelectionEnd(newValueInit, newValueEnd, _laps); 401 | } 402 | } 403 | return; 404 | } 405 | 406 | // isDoubleHandler but one handler was selected 407 | if (_isInitHandlerSelected) { 408 | widget.onSelectionChange(newValue, widget.end, _laps); 409 | if (isPanEnd) { 410 | widget.onSelectionEnd(newValue, widget.end, _laps); 411 | } 412 | } else { 413 | widget.onSelectionChange(widget.init, newValue, _laps); 414 | if (isPanEnd) { 415 | widget.onSelectionEnd(widget.init, newValue, _laps); 416 | } 417 | } 418 | } 419 | 420 | bool _onPanDown(Offset details) { 421 | if (_painter == null) { 422 | return false; 423 | } 424 | RenderBox renderBox = context.findRenderObject(); 425 | var position = renderBox.globalToLocal(details); 426 | 427 | if (position == null) { 428 | return false; 429 | } 430 | 431 | if (isSingleHandler) { 432 | if (_isPointAlongCircle(position, _painter.center, _painter.radius)) { 433 | _isEndHandlerSelected = true; 434 | _onPanUpdate(details); 435 | } 436 | } else { 437 | _isInitHandlerSelected = _isPointInsideCircle( 438 | position, _painter.initHandler, widget.handlerOutterRadius); 439 | 440 | if (!_isInitHandlerSelected) { 441 | _isEndHandlerSelected = _isPointInsideCircle( 442 | position, _painter.endHandler, widget.handlerOutterRadius); 443 | } 444 | 445 | if (isNoHandlersSelected) { 446 | // we check if the user pressed in the selection in a double handler slider 447 | // that means the user wants to move the selection as a whole 448 | if (_isPointAlongCircle(position, _painter.center, _painter.radius)) { 449 | var angle = _coordinatesToRadians(_painter.center, position); 450 | if (_isAngleInsideRadiansSelection(angle, _startAngle, _sweepAngle)) { 451 | _isEndHandlerSelected = true; 452 | _isInitHandlerSelected = true; 453 | var positionPercentage = _radiansToPercentage(angle); 454 | 455 | // no need to account for negative values, that will be sorted out in the onPanUpdate 456 | _differenceFromInitPoint = 457 | _percentageToValue(positionPercentage, widget.divisions) - 458 | widget.init; 459 | } 460 | } 461 | } 462 | } 463 | return _isInitHandlerSelected || _isEndHandlerSelected; 464 | } 465 | } 466 | 467 | class SliderPainter extends CustomPainter { 468 | CircularSliderMode mode; 469 | double startAngle; 470 | double endAngle; 471 | double sweepAngle; 472 | Color selectionColor; 473 | Color handlerColor; 474 | double handlerOutterRadius; 475 | bool showRoundedCapInSelection; 476 | bool showHandlerOutter; 477 | double sliderStrokeWidth; 478 | 479 | Offset initHandler; 480 | Offset endHandler; 481 | Offset center; 482 | double radius; 483 | 484 | SliderPainter({ 485 | @required this.mode, 486 | @required this.startAngle, 487 | @required this.endAngle, 488 | @required this.sweepAngle, 489 | @required this.selectionColor, 490 | @required this.handlerColor, 491 | @required this.handlerOutterRadius, 492 | @required this.showRoundedCapInSelection, 493 | @required this.showHandlerOutter, 494 | @required this.sliderStrokeWidth, 495 | }); 496 | 497 | @override 498 | void paint(Canvas canvas, Size size) { 499 | Paint progress = _getPaint(color: selectionColor); 500 | 501 | center = Offset(size.width / 2, size.height / 2); 502 | radius = min(size.width / 2, size.height / 2) - sliderStrokeWidth; 503 | 504 | canvas.drawArc(Rect.fromCircle(center: center, radius: radius), 505 | -pi / 2 + startAngle, sweepAngle, false, progress); 506 | 507 | Paint handler = _getPaint(color: handlerColor, style: PaintingStyle.fill); 508 | Paint handlerOutter = _getPaint(color: handlerColor, width: 2.0); 509 | 510 | // draw handlers 511 | if (mode == CircularSliderMode.doubleHandler) { 512 | initHandler = _radiansToCoordinates(center, -pi / 2 + startAngle, radius); 513 | canvas.drawCircle(initHandler, 8.0, handler); 514 | canvas.drawCircle(initHandler, handlerOutterRadius, handlerOutter); 515 | } 516 | 517 | endHandler = _radiansToCoordinates(center, -pi / 2 + endAngle, radius); 518 | canvas.drawCircle(endHandler, 8.0, handler); 519 | if (showHandlerOutter) { 520 | canvas.drawCircle(endHandler, handlerOutterRadius, handlerOutter); 521 | } 522 | } 523 | 524 | Paint _getPaint({@required Color color, double width, PaintingStyle style}) => 525 | Paint() 526 | ..color = color 527 | ..strokeCap = 528 | showRoundedCapInSelection ? StrokeCap.round : StrokeCap.butt 529 | ..style = style ?? PaintingStyle.stroke 530 | ..strokeWidth = width ?? sliderStrokeWidth; 531 | 532 | @override 533 | bool shouldRepaint(CustomPainter oldDelegate) { 534 | return true; 535 | } 536 | } 537 | 538 | class CustomPanGestureRecognizer extends OneSequenceGestureRecognizer { 539 | final Function onPanDown; 540 | final Function onPanUpdate; 541 | final Function onPanEnd; 542 | 543 | CustomPanGestureRecognizer({ 544 | @required this.onPanDown, 545 | @required this.onPanUpdate, 546 | @required this.onPanEnd, 547 | }); 548 | 549 | @override 550 | void addPointer(PointerEvent event) { 551 | if (onPanDown(event.position)) { 552 | startTrackingPointer(event.pointer); 553 | resolve(GestureDisposition.accepted); 554 | } else { 555 | stopTrackingPointer(event.pointer); 556 | } 557 | } 558 | 559 | @override 560 | void handleEvent(PointerEvent event) { 561 | if (event is PointerMoveEvent) { 562 | onPanUpdate(event.position); 563 | } 564 | if (event is PointerUpEvent) { 565 | onPanEnd(event.position); 566 | stopTrackingPointer(event.pointer); 567 | } 568 | } 569 | 570 | @override 571 | String get debugDescription => 'customPan'; 572 | 573 | @override 574 | void didStopTrackingLastPointer(int pointer) {} 575 | } 576 | 577 | class BasePainter extends CustomPainter { 578 | Color baseColor; 579 | Color selectionColor; 580 | int primarySectors; 581 | int secondarySectors; 582 | double sliderStrokeWidth; 583 | 584 | Offset center; 585 | double radius; 586 | 587 | BasePainter({ 588 | @required this.baseColor, 589 | @required this.selectionColor, 590 | @required this.primarySectors, 591 | @required this.secondarySectors, 592 | @required this.sliderStrokeWidth, 593 | }); 594 | 595 | @override 596 | void paint(Canvas canvas, Size size) { 597 | Paint base = _getPaint(color: baseColor); 598 | 599 | center = Offset(size.width / 2, size.height / 2); 600 | radius = min(size.width / 2, size.height / 2) - sliderStrokeWidth; 601 | // we need this in the parent to calculate if the user clicks on the circumference 602 | 603 | assert(radius > 0); 604 | 605 | canvas.drawCircle(center, radius, base); 606 | 607 | if (primarySectors > 0) { 608 | _paintSectors(primarySectors, 8.0, selectionColor, canvas); 609 | } 610 | 611 | if (secondarySectors > 0) { 612 | _paintSectors(secondarySectors, 6.0, baseColor, canvas); 613 | } 614 | } 615 | 616 | void _paintSectors( 617 | int sectors, double radiusPadding, Color color, Canvas canvas) { 618 | Paint section = _getPaint(color: color, width: 2.0); 619 | 620 | var endSectors = _getSectionsCoordinatesInCircle( 621 | center, radius + radiusPadding, sectors); 622 | var initSectors = _getSectionsCoordinatesInCircle( 623 | center, radius - radiusPadding, sectors); 624 | _paintLines(canvas, initSectors, endSectors, section); 625 | } 626 | 627 | void _paintLines( 628 | Canvas canvas, List inits, List ends, Paint section) { 629 | assert(inits.length == ends.length && inits.length > 0); 630 | 631 | for (var i = 0; i < inits.length; i++) { 632 | canvas.drawLine(inits[i], ends[i], section); 633 | } 634 | } 635 | 636 | Paint _getPaint({@required Color color, double width, PaintingStyle style}) => 637 | Paint() 638 | ..color = color 639 | ..strokeCap = StrokeCap.round 640 | ..style = style ?? PaintingStyle.stroke 641 | ..strokeWidth = width ?? sliderStrokeWidth; 642 | 643 | @override 644 | bool shouldRepaint(CustomPainter oldDelegate) { 645 | return false; 646 | } 647 | } 648 | 649 | //UTILS 650 | double _percentageToRadians(double percentage) => ((2 * pi * percentage) / 100); 651 | 652 | double _radiansToPercentage(double radians) { 653 | var normalized = radians < 0 ? -radians : 2 * pi - radians; 654 | var percentage = ((100 * normalized) / (2 * pi)); 655 | // TODO we have an inconsistency of pi/2 in terms of percentage and radians 656 | return (percentage + 25) % 100; 657 | } 658 | 659 | double _coordinatesToRadians(Offset center, Offset coords) { 660 | var a = coords.dx - center.dx; 661 | var b = center.dy - coords.dy; 662 | return atan2(b, a); 663 | } 664 | 665 | Offset _radiansToCoordinates(Offset center, double radians, double radius) { 666 | var dx = center.dx + radius * cos(radians); 667 | var dy = center.dy + radius * sin(radians); 668 | return Offset(dx, dy); 669 | } 670 | 671 | double _valueToPercentage(int time, int intervals) => (time / intervals) * 100; 672 | 673 | int _percentageToValue(double percentage, int intervals) => 674 | ((percentage * intervals) / 100).round(); 675 | 676 | bool _isPointInsideCircle(Offset point, Offset center, double rradius) { 677 | var radius = rradius * 1.2; 678 | return point.dx < (center.dx + radius) && 679 | point.dx > (center.dx - radius) && 680 | point.dy < (center.dy + radius) && 681 | point.dy > (center.dy - radius); 682 | } 683 | 684 | bool _isPointAlongCircle(Offset point, Offset center, double radius) { 685 | // distance is root(sqr(x2 - x1) + sqr(y2 - y1)) 686 | // i.e., (7,8) and (3,2) -> 7.21 687 | var d1 = pow(point.dx - center.dx, 2); 688 | var d2 = pow(point.dy - center.dy, 2); 689 | var distance = sqrt(d1 + d2); 690 | return (distance - radius).abs() < 10; 691 | } 692 | 693 | double _getSweepAngle(double init, double end) { 694 | if (end > init) { 695 | return end - init; 696 | } 697 | return (100 - init + end).abs(); 698 | } 699 | 700 | List _getSectionsCoordinatesInCircle( 701 | Offset center, double radius, int sections) { 702 | var intervalAngle = (pi * 2) / sections; 703 | return List.generate(sections, (int index) => index).map((i) { 704 | var radians = (pi / 2) + (intervalAngle * i); 705 | return _radiansToCoordinates(center, radians, radius); 706 | }).toList(); 707 | } 708 | 709 | bool _isAngleInsideRadiansSelection(double angle, double start, double sweep) { 710 | var normalized = angle > pi / 2 ? 5 * pi / 2 - angle : pi / 2 - angle; 711 | var end = (start + sweep) % (2 * pi); 712 | return end > start 713 | ? normalized > start && normalized < end 714 | : normalized > start || normalized < end; 715 | } 716 | 717 | // this is not 100% accurate but it works 718 | // we just want to see if a value changed drastically its value 719 | bool _radiansWasModuloed(double current, double previous) { 720 | return (previous - current).abs() > (3 * pi / 2); 721 | } 722 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/widgets/increase_slider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | class IncreaseSlider extends StatefulWidget { 6 | final double min; 7 | final double max; 8 | final double interval; 9 | final Function(double) onUpdate; 10 | 11 | IncreaseSlider( 12 | {this.min = 0, this.max = 100, this.interval = 1, this.onUpdate}); 13 | 14 | @override 15 | _IncreaseSliderState createState() => _IncreaseSliderState(); 16 | } 17 | 18 | class _IncreaseSliderState extends State { 19 | double currentValue = 0; 20 | double dx = 0; 21 | Timer timer; 22 | 23 | @override 24 | Widget build(BuildContext context) { 25 | double width = 300; 26 | double height = 50; 27 | double indicatorWidth = height; 28 | 29 | return Stack( 30 | children: [ 31 | Container( 32 | height: height, 33 | width: width, 34 | padding: EdgeInsets.all(10), 35 | decoration: BoxDecoration( 36 | borderRadius: BorderRadius.circular(height), 37 | gradient: LinearGradient(colors: [Colors.red, Colors.blue])), 38 | child: Row( 39 | mainAxisAlignment: MainAxisAlignment.spaceBetween, 40 | children: [ 41 | Icon( 42 | Icons.remove, 43 | color: Colors.white, 44 | ), 45 | Icon( 46 | Icons.add, 47 | color: Colors.white, 48 | ) 49 | ], 50 | ), 51 | ), 52 | GestureDetector( 53 | onHorizontalDragUpdate: (DragUpdateDetails d) { 54 | // print(d.delta.dx); 55 | setState(() { 56 | dx += d.delta.dx; 57 | }); 58 | timer?.cancel(); 59 | // print(dx.floor()); 60 | timer = Timer.periodic( 61 | Duration( 62 | milliseconds: (300 / 2 - (dx.floor()).abs() + 1).floor()), 63 | (timer) { 64 | setState(() { 65 | if (dx < 0 && currentValue > widget.min) { 66 | currentValue -= widget.interval; 67 | } else if (dx > 0 && currentValue < widget.max) { 68 | currentValue += widget.interval; 69 | } 70 | }); 71 | if (widget.onUpdate != null) { 72 | widget.onUpdate(currentValue); 73 | } 74 | }); 75 | }, 76 | onHorizontalDragEnd: (DragEndDetails d) { 77 | setState(() { 78 | dx = 0; 79 | }); 80 | timer?.cancel(); 81 | }, 82 | child: AnimatedContainer( 83 | duration: Duration(milliseconds: 100), 84 | margin: EdgeInsets.only( 85 | left: (width / 2 - indicatorWidth / 2 + dx) < 0 86 | ? 0 87 | : (width / 2 - indicatorWidth / 2 + dx) > 88 | width - indicatorWidth 89 | ? width - indicatorWidth 90 | : (width / 2 - indicatorWidth / 2 + dx)), 91 | width: indicatorWidth, 92 | height: height, 93 | decoration: BoxDecoration( 94 | borderRadius: BorderRadius.circular(height), 95 | border: Border.all(color: Colors.white, width: 3)), 96 | ), 97 | ), 98 | ], 99 | ); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/lib/src/widgets/no_glowable_scroll_view.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class NoGrowScrollView extends StatelessWidget { 4 | final Widget child; 5 | 6 | NoGrowScrollView({@required this.child}); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return Container( 11 | child: NotificationListener( 12 | onNotification: (OverscrollIndicatorNotification ovs) { 13 | ovs.disallowGlow(); 14 | return true; 15 | }, 16 | child: child), 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "2.5.0" 11 | boolean_selector: 12 | dependency: transitive 13 | description: 14 | name: boolean_selector 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "2.1.0" 18 | characters: 19 | dependency: transitive 20 | description: 21 | name: characters 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "1.1.0" 25 | charcode: 26 | dependency: transitive 27 | description: 28 | name: charcode 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "1.2.0" 32 | chewie: 33 | dependency: transitive 34 | description: 35 | name: chewie 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "0.12.2" 39 | chewie_audio: 40 | dependency: transitive 41 | description: 42 | name: chewie_audio 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "1.1.2" 46 | clock: 47 | dependency: transitive 48 | description: 49 | name: clock 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "1.1.0" 53 | collection: 54 | dependency: transitive 55 | description: 56 | name: collection 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "1.15.0" 60 | css_colors: 61 | dependency: transitive 62 | description: 63 | name: css_colors 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "1.1.0" 67 | csslib: 68 | dependency: transitive 69 | description: 70 | name: csslib 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "0.16.2" 74 | cupertino_icons: 75 | dependency: "direct main" 76 | description: 77 | name: cupertino_icons 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "1.0.2" 81 | fake_async: 82 | dependency: transitive 83 | description: 84 | name: fake_async 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "1.2.0" 88 | ffi: 89 | dependency: transitive 90 | description: 91 | name: ffi 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "1.0.0" 95 | file: 96 | dependency: transitive 97 | description: 98 | name: file 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "6.1.0" 102 | flutter: 103 | dependency: "direct main" 104 | description: flutter 105 | source: sdk 106 | version: "0.0.0" 107 | flutter_colorpicker: 108 | dependency: "direct main" 109 | description: 110 | name: flutter_colorpicker 111 | url: "https://pub.dartlang.org" 112 | source: hosted 113 | version: "0.4.0" 114 | flutter_html: 115 | dependency: "direct main" 116 | description: 117 | name: flutter_html 118 | url: "https://pub.dartlang.org" 119 | source: hosted 120 | version: "1.3.0" 121 | flutter_layout_grid: 122 | dependency: transitive 123 | description: 124 | name: flutter_layout_grid 125 | url: "https://pub.dartlang.org" 126 | source: hosted 127 | version: "0.10.5" 128 | flutter_spinkit: 129 | dependency: "direct main" 130 | description: 131 | name: flutter_spinkit 132 | url: "https://pub.dartlang.org" 133 | source: hosted 134 | version: "5.0.0" 135 | flutter_svg: 136 | dependency: transitive 137 | description: 138 | name: flutter_svg 139 | url: "https://pub.dartlang.org" 140 | source: hosted 141 | version: "0.20.0-nullsafety.3" 142 | flutter_test: 143 | dependency: "direct dev" 144 | description: flutter 145 | source: sdk 146 | version: "0.0.0" 147 | flutter_web_plugins: 148 | dependency: transitive 149 | description: flutter 150 | source: sdk 151 | version: "0.0.0" 152 | font_awesome_flutter: 153 | dependency: "direct main" 154 | description: 155 | name: font_awesome_flutter 156 | url: "https://pub.dartlang.org" 157 | source: hosted 158 | version: "9.0.0" 159 | html: 160 | dependency: transitive 161 | description: 162 | name: html 163 | url: "https://pub.dartlang.org" 164 | source: hosted 165 | version: "0.14.0+4" 166 | import_js_library: 167 | dependency: transitive 168 | description: 169 | name: import_js_library 170 | url: "https://pub.dartlang.org" 171 | source: hosted 172 | version: "1.0.2" 173 | js: 174 | dependency: transitive 175 | description: 176 | name: js 177 | url: "https://pub.dartlang.org" 178 | source: hosted 179 | version: "0.6.3" 180 | matcher: 181 | dependency: transitive 182 | description: 183 | name: matcher 184 | url: "https://pub.dartlang.org" 185 | source: hosted 186 | version: "0.12.10" 187 | meta: 188 | dependency: transitive 189 | description: 190 | name: meta 191 | url: "https://pub.dartlang.org" 192 | source: hosted 193 | version: "1.3.0" 194 | mime: 195 | dependency: transitive 196 | description: 197 | name: mime 198 | url: "https://pub.dartlang.org" 199 | source: hosted 200 | version: "1.0.0" 201 | path: 202 | dependency: transitive 203 | description: 204 | name: path 205 | url: "https://pub.dartlang.org" 206 | source: hosted 207 | version: "1.8.0" 208 | path_drawing: 209 | dependency: transitive 210 | description: 211 | name: path_drawing 212 | url: "https://pub.dartlang.org" 213 | source: hosted 214 | version: "0.5.0-nullsafety.0" 215 | path_parsing: 216 | dependency: transitive 217 | description: 218 | name: path_parsing 219 | url: "https://pub.dartlang.org" 220 | source: hosted 221 | version: "0.2.0-nullsafety.0" 222 | path_provider: 223 | dependency: "direct main" 224 | description: 225 | name: path_provider 226 | url: "https://pub.dartlang.org" 227 | source: hosted 228 | version: "2.0.1" 229 | path_provider_linux: 230 | dependency: transitive 231 | description: 232 | name: path_provider_linux 233 | url: "https://pub.dartlang.org" 234 | source: hosted 235 | version: "2.0.0" 236 | path_provider_macos: 237 | dependency: transitive 238 | description: 239 | name: path_provider_macos 240 | url: "https://pub.dartlang.org" 241 | source: hosted 242 | version: "2.0.0" 243 | path_provider_platform_interface: 244 | dependency: transitive 245 | description: 246 | name: path_provider_platform_interface 247 | url: "https://pub.dartlang.org" 248 | source: hosted 249 | version: "2.0.1" 250 | path_provider_windows: 251 | dependency: transitive 252 | description: 253 | name: path_provider_windows 254 | url: "https://pub.dartlang.org" 255 | source: hosted 256 | version: "2.0.0" 257 | permission_handler: 258 | dependency: "direct main" 259 | description: 260 | name: permission_handler 261 | url: "https://pub.dartlang.org" 262 | source: hosted 263 | version: "6.1.1" 264 | permission_handler_platform_interface: 265 | dependency: transitive 266 | description: 267 | name: permission_handler_platform_interface 268 | url: "https://pub.dartlang.org" 269 | source: hosted 270 | version: "3.1.1" 271 | petitparser: 272 | dependency: transitive 273 | description: 274 | name: petitparser 275 | url: "https://pub.dartlang.org" 276 | source: hosted 277 | version: "4.0.2" 278 | platform: 279 | dependency: transitive 280 | description: 281 | name: platform 282 | url: "https://pub.dartlang.org" 283 | source: hosted 284 | version: "3.0.0" 285 | plugin_platform_interface: 286 | dependency: transitive 287 | description: 288 | name: plugin_platform_interface 289 | url: "https://pub.dartlang.org" 290 | source: hosted 291 | version: "2.0.0" 292 | process: 293 | dependency: transitive 294 | description: 295 | name: process 296 | url: "https://pub.dartlang.org" 297 | source: hosted 298 | version: "4.2.1" 299 | quiver: 300 | dependency: transitive 301 | description: 302 | name: quiver 303 | url: "https://pub.dartlang.org" 304 | source: hosted 305 | version: "2.1.5" 306 | reorderables: 307 | dependency: "direct main" 308 | description: 309 | name: reorderables 310 | url: "https://pub.dartlang.org" 311 | source: hosted 312 | version: "0.4.0" 313 | rxdart: 314 | dependency: "direct main" 315 | description: 316 | name: rxdart 317 | url: "https://pub.dartlang.org" 318 | source: hosted 319 | version: "0.26.0" 320 | share: 321 | dependency: "direct main" 322 | description: 323 | name: share 324 | url: "https://pub.dartlang.org" 325 | source: hosted 326 | version: "2.0.1" 327 | sky_engine: 328 | dependency: transitive 329 | description: flutter 330 | source: sdk 331 | version: "0.0.99" 332 | source_span: 333 | dependency: transitive 334 | description: 335 | name: source_span 336 | url: "https://pub.dartlang.org" 337 | source: hosted 338 | version: "1.8.0" 339 | stack_trace: 340 | dependency: transitive 341 | description: 342 | name: stack_trace 343 | url: "https://pub.dartlang.org" 344 | source: hosted 345 | version: "1.10.0" 346 | stream_channel: 347 | dependency: transitive 348 | description: 349 | name: stream_channel 350 | url: "https://pub.dartlang.org" 351 | source: hosted 352 | version: "2.1.0" 353 | string_scanner: 354 | dependency: transitive 355 | description: 356 | name: string_scanner 357 | url: "https://pub.dartlang.org" 358 | source: hosted 359 | version: "1.1.0" 360 | term_glyph: 361 | dependency: transitive 362 | description: 363 | name: term_glyph 364 | url: "https://pub.dartlang.org" 365 | source: hosted 366 | version: "1.2.0" 367 | test_api: 368 | dependency: transitive 369 | description: 370 | name: test_api 371 | url: "https://pub.dartlang.org" 372 | source: hosted 373 | version: "0.2.19" 374 | typed_data: 375 | dependency: transitive 376 | description: 377 | name: typed_data 378 | url: "https://pub.dartlang.org" 379 | source: hosted 380 | version: "1.3.0" 381 | vector_math: 382 | dependency: transitive 383 | description: 384 | name: vector_math 385 | url: "https://pub.dartlang.org" 386 | source: hosted 387 | version: "2.1.0" 388 | video_player: 389 | dependency: transitive 390 | description: 391 | name: video_player 392 | url: "https://pub.dartlang.org" 393 | source: hosted 394 | version: "1.0.1" 395 | video_player_platform_interface: 396 | dependency: transitive 397 | description: 398 | name: video_player_platform_interface 399 | url: "https://pub.dartlang.org" 400 | source: hosted 401 | version: "2.2.0" 402 | video_player_web: 403 | dependency: transitive 404 | description: 405 | name: video_player_web 406 | url: "https://pub.dartlang.org" 407 | source: hosted 408 | version: "0.1.4+1" 409 | wakelock: 410 | dependency: transitive 411 | description: 412 | name: wakelock 413 | url: "https://pub.dartlang.org" 414 | source: hosted 415 | version: "0.2.1+1" 416 | wakelock_platform_interface: 417 | dependency: transitive 418 | description: 419 | name: wakelock_platform_interface 420 | url: "https://pub.dartlang.org" 421 | source: hosted 422 | version: "0.1.0+1" 423 | wakelock_web: 424 | dependency: transitive 425 | description: 426 | name: wakelock_web 427 | url: "https://pub.dartlang.org" 428 | source: hosted 429 | version: "0.1.0+3" 430 | wallpaper_manager: 431 | dependency: "direct main" 432 | description: 433 | name: wallpaper_manager 434 | url: "https://pub.dartlang.org" 435 | source: hosted 436 | version: "1.0.10" 437 | webview_flutter: 438 | dependency: transitive 439 | description: 440 | name: webview_flutter 441 | url: "https://pub.dartlang.org" 442 | source: hosted 443 | version: "1.0.7" 444 | win32: 445 | dependency: transitive 446 | description: 447 | name: win32 448 | url: "https://pub.dartlang.org" 449 | source: hosted 450 | version: "2.0.5" 451 | xdg_directories: 452 | dependency: transitive 453 | description: 454 | name: xdg_directories 455 | url: "https://pub.dartlang.org" 456 | source: hosted 457 | version: "0.2.0" 458 | xml: 459 | dependency: transitive 460 | description: 461 | name: xml 462 | url: "https://pub.dartlang.org" 463 | source: hosted 464 | version: "5.0.2" 465 | sdks: 466 | dart: ">=2.12.0 <3.0.0" 467 | flutter: ">=2.0.0" 468 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: ankii_flutter_gradient 2 | description: A new Flutter application. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | # The following defines the version and build number for your application. 9 | # A version number is three numbers separated by dots, like 1.2.43 10 | # followed by an optional build number separated by a +. 11 | # Both the version and the builder number may be overridden in flutter 12 | # build by specifying --build-name and --build-number, respectively. 13 | # In Android, build-name is used as versionName while build-number used as versionCode. 14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning 15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. 16 | # Read more about iOS versioning at 17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html 18 | version: 1.0.0+1 19 | 20 | environment: 21 | sdk: ">=2.10.0 <3.0.0" 22 | 23 | dependencies: 24 | flutter: 25 | sdk: flutter 26 | 27 | 28 | # The following adds the Cupertino Icons font to your application. 29 | # Use with the CupertinoIcons class for iOS style icons. 30 | cupertino_icons: ^1.0.2 31 | flutter_colorpicker: ^0.4.0 32 | rxdart: ^0.26.0 33 | font_awesome_flutter: ^9.0.0 34 | flutter_spinkit: ^5.0.0 35 | reorderables: ^0.4.0 36 | flutter_html: ^1.0.2 37 | share: ^2.0.1 38 | path_provider: ^2.0.1 39 | wallpaper_manager: ^1.0.10 40 | permission_handler: ^6.1.1 41 | 42 | dev_dependencies: 43 | flutter_test: 44 | sdk: flutter 45 | 46 | # For information on the generic Dart part of this file, see the 47 | # following page: https://dart.dev/tools/pub/pubspec 48 | 49 | # The following section is specific to Flutter. 50 | flutter: 51 | 52 | # The following line ensures that the Material Icons font is 53 | # included with your application, so that you can use the icons in 54 | # the material Icons class. 55 | uses-material-design: true 56 | assets: 57 | - assets/transparent.jpg 58 | 59 | # To add assets to your application, add an assets section, like this: 60 | # assets: 61 | # - images/a_dot_burr.jpeg 62 | # - images/a_dot_ham.jpeg 63 | 64 | # An image asset can refer to one or more resolution-specific "variants", see 65 | # https://flutter.dev/assets-and-images/#resolution-aware. 66 | 67 | # For details regarding adding assets from package dependencies, see 68 | # https://flutter.dev/assets-and-images/#from-packages 69 | 70 | # To add custom fonts to your application, add a fonts section here, 71 | # in this "flutter" section. Each entry in this list should have a 72 | # "family" key with the font family name, and a "fonts" key with a 73 | # list giving the asset and other descriptors for the font. For 74 | # example: 75 | # fonts: 76 | # - family: Schyler 77 | # fonts: 78 | # - asset: fonts/Schyler-Regular.ttf 79 | # - asset: fonts/Schyler-Italic.ttf 80 | # style: italic 81 | # - family: Trajan Pro 82 | # fonts: 83 | # - asset: fonts/TrajanPro.ttf 84 | # - asset: fonts/TrajanPro_Bold.ttf 85 | # weight: 700 86 | # 87 | # For details regarding fonts from package dependencies, 88 | # see https://flutter.dev/custom-fonts/#from-packages 89 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:ankii_flutter_gradient/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/web/favicon.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/web/icons/Icon-192.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/ankii_flutter_gradient/web/icons/Icon-512.png -------------------------------------------------------------------------------- /ankii_flutter_gradient/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | ankii_flutter_gradient 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /ankii_flutter_gradient/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ankii_flutter_gradient", 3 | "short_name": "ankii_flutter_gradient", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/app_icon.png -------------------------------------------------------------------------------- /app_icon.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/app_icon.psd -------------------------------------------------------------------------------- /web/.last_build_id: -------------------------------------------------------------------------------- 1 | 1ad7a5191f8f764b52b077d2d6177fa2 -------------------------------------------------------------------------------- /web/assets/AssetManifest.json: -------------------------------------------------------------------------------- 1 | {"assets/transparent.jpg":["assets/transparent.jpg"],"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"],"packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf":["packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf"],"packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf":["packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf"],"packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf":["packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf"],"packages/wakelock_web/assets/no_sleep.js":["packages/wakelock_web/assets/no_sleep.js"]} -------------------------------------------------------------------------------- /web/assets/FontManifest.json: -------------------------------------------------------------------------------- 1 | [{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]},{"family":"packages/font_awesome_flutter/FontAwesomeBrands","fonts":[{"weight":400,"asset":"packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf"}]},{"family":"packages/font_awesome_flutter/FontAwesomeRegular","fonts":[{"weight":400,"asset":"packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf"}]},{"family":"packages/font_awesome_flutter/FontAwesomeSolid","fonts":[{"weight":900,"asset":"packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf"}]}] -------------------------------------------------------------------------------- /web/assets/assets/transparent.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/assets/assets/transparent.jpg -------------------------------------------------------------------------------- /web/assets/fonts/MaterialIcons-Regular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/assets/fonts/MaterialIcons-Regular.otf -------------------------------------------------------------------------------- /web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/assets/packages/cupertino_icons/assets/CupertinoIcons.ttf -------------------------------------------------------------------------------- /web/assets/packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/assets/packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /web/assets/packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/assets/packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /web/assets/packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/assets/packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /web/assets/packages/wakelock_web/assets/no_sleep.js: -------------------------------------------------------------------------------- 1 | var webm = 2 | 'data:video/webm;base64,GkXfo0AgQoaBAUL3gQFC8oEEQvOBCEKCQAR3ZWJtQoeBAkKFgQIYU4BnQI0VSalmQCgq17FAAw9CQE2AQAZ3aGFtbXlXQUAGd2hhbW15RIlACECPQAAAAAAAFlSua0AxrkAu14EBY8WBAZyBACK1nEADdW5khkAFVl9WUDglhohAA1ZQOIOBAeBABrCBCLqBCB9DtnVAIueBAKNAHIEAAIAwAQCdASoIAAgAAUAmJaQAA3AA/vz0AAA=' 3 | var mp4 = 4 | 'data:video/mp4;base64,AAAAIGZ0eXBtcDQyAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZnJlZQAACKBtZGF0AAAC8wYF///v3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDE0MiByMjQ3OSBkZDc5YTYxIC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMjAxNCAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYmFjPTEgcmVmPTEgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibWU9MiBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MCA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0wIHRocmVhZHM9NiBsb29rYWhlYWRfdGhyZWFkcz0xIHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTIgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MSBvcGVuX2dvcD0wIHdlaWdodHA9MSBrZXlpbnQ9MzAwIGtleWludF9taW49MzAgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD0xMCByYz1jcmYgbWJ0cmVlPTEgY3JmPTIwLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IHZidl9tYXhyYXRlPTIwMDAwIHZidl9idWZzaXplPTI1MDAwIGNyZl9tYXg9MC4wIG5hbF9ocmQ9bm9uZSBmaWxsZXI9MCBpcF9yYXRpbz0xLjQwIGFxPTE6MS4wMACAAAAAOWWIhAA3//p+C7v8tDDSTjf97w55i3SbRPO4ZY+hkjD5hbkAkL3zpJ6h/LR1CAABzgB1kqqzUorlhQAAAAxBmiQYhn/+qZYADLgAAAAJQZ5CQhX/AAj5IQADQGgcIQADQGgcAAAACQGeYUQn/wALKCEAA0BoHAAAAAkBnmNEJ/8ACykhAANAaBwhAANAaBwAAAANQZpoNExDP/6plgAMuSEAA0BoHAAAAAtBnoZFESwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBnqVEJ/8ACykhAANAaBwAAAAJAZ6nRCf/AAsoIQADQGgcIQADQGgcAAAADUGarDRMQz/+qZYADLghAANAaBwAAAALQZ7KRRUsK/8ACPkhAANAaBwAAAAJAZ7pRCf/AAsoIQADQGgcIQADQGgcAAAACQGe60Qn/wALKCEAA0BoHAAAAA1BmvA0TEM//qmWAAy5IQADQGgcIQADQGgcAAAAC0GfDkUVLCv/AAj5IQADQGgcAAAACQGfLUQn/wALKSEAA0BoHCEAA0BoHAAAAAkBny9EJ/8ACyghAANAaBwAAAANQZs0NExDP/6plgAMuCEAA0BoHAAAAAtBn1JFFSwr/wAI+SEAA0BoHCEAA0BoHAAAAAkBn3FEJ/8ACyghAANAaBwAAAAJAZ9zRCf/AAsoIQADQGgcIQADQGgcAAAADUGbeDRMQz/+qZYADLkhAANAaBwAAAALQZ+WRRUsK/8ACPghAANAaBwhAANAaBwAAAAJAZ+1RCf/AAspIQADQGgcAAAACQGft0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bm7w0TEM//qmWAAy4IQADQGgcAAAAC0Gf2kUVLCv/AAj5IQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHAAAAAkBn/tEJ/8ACykhAANAaBwAAAANQZvgNExDP/6plgAMuSEAA0BoHCEAA0BoHAAAAAtBnh5FFSwr/wAI+CEAA0BoHAAAAAkBnj1EJ/8ACyghAANAaBwhAANAaBwAAAAJAZ4/RCf/AAspIQADQGgcAAAADUGaJDRMQz/+qZYADLghAANAaBwAAAALQZ5CRRUsK/8ACPkhAANAaBwhAANAaBwAAAAJAZ5hRCf/AAsoIQADQGgcAAAACQGeY0Qn/wALKSEAA0BoHCEAA0BoHAAAAA1Bmmg0TEM//qmWAAy5IQADQGgcAAAAC0GehkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGepUQn/wALKSEAA0BoHAAAAAkBnqdEJ/8ACyghAANAaBwAAAANQZqsNExDP/6plgAMuCEAA0BoHCEAA0BoHAAAAAtBnspFFSwr/wAI+SEAA0BoHAAAAAkBnulEJ/8ACyghAANAaBwhAANAaBwAAAAJAZ7rRCf/AAsoIQADQGgcAAAADUGa8DRMQz/+qZYADLkhAANAaBwhAANAaBwAAAALQZ8ORRUsK/8ACPkhAANAaBwAAAAJAZ8tRCf/AAspIQADQGgcIQADQGgcAAAACQGfL0Qn/wALKCEAA0BoHAAAAA1BmzQ0TEM//qmWAAy4IQADQGgcAAAAC0GfUkUVLCv/AAj5IQADQGgcIQADQGgcAAAACQGfcUQn/wALKCEAA0BoHAAAAAkBn3NEJ/8ACyghAANAaBwhAANAaBwAAAANQZt4NExC//6plgAMuSEAA0BoHAAAAAtBn5ZFFSwr/wAI+CEAA0BoHCEAA0BoHAAAAAkBn7VEJ/8ACykhAANAaBwAAAAJAZ+3RCf/AAspIQADQGgcAAAADUGbuzRMQn/+nhAAYsAhAANAaBwhAANAaBwAAAAJQZ/aQhP/AAspIQADQGgcAAAACQGf+UQn/wALKCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHCEAA0BoHAAACiFtb292AAAAbG12aGQAAAAA1YCCX9WAgl8AAAPoAAAH/AABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAGGlvZHMAAAAAEICAgAcAT////v7/AAAF+XRyYWsAAABcdGtoZAAAAAPVgIJf1YCCXwAAAAEAAAAAAAAH0AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAygAAAMoAAAAAACRlZHRzAAAAHGVsc3QAAAAAAAAAAQAAB9AAABdwAAEAAAAABXFtZGlhAAAAIG1kaGQAAAAA1YCCX9WAgl8AAV+QAAK/IFXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAUcbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybCAAAAABAAAE3HN0YmwAAACYc3RzZAAAAAAAAAABAAAAiGF2YzEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAygDKAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAyYXZjQwFNQCj/4QAbZ01AKOyho3ySTUBAQFAAAAMAEAAr8gDxgxlgAQAEaO+G8gAAABhzdHRzAAAAAAAAAAEAAAA8AAALuAAAABRzdHNzAAAAAAAAAAEAAAABAAAB8GN0dHMAAAAAAAAAPAAAAAEAABdwAAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAADqYAAAAAQAAF3AAAAABAAAAAAAAAAEAAAu4AAAAAQAAOpgAAAABAAAXcAAAAAEAAAAAAAAAAQAAC7gAAAABAAA6mAAAAAEAABdwAAAAAQAAAAAAAAABAAALuAAAAAEAAC7gAAAAAQAAF3AAAAABAAAAAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAEEc3RzegAAAAAAAAAAAAAAPAAAAzQAAAAQAAAADQAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAAPAAAADQAAAA0AAAARAAAADwAAAA0AAAANAAAAEQAAAA8AAAANAAAADQAAABEAAAANAAAADQAAAQBzdGNvAAAAAAAAADwAAAAwAAADZAAAA3QAAAONAAADoAAAA7kAAAPQAAAD6wAAA/4AAAQXAAAELgAABEMAAARcAAAEbwAABIwAAAShAAAEugAABM0AAATkAAAE/wAABRIAAAUrAAAFQgAABV0AAAVwAAAFiQAABaAAAAW1AAAFzgAABeEAAAX+AAAGEwAABiwAAAY/AAAGVgAABnEAAAaEAAAGnQAABrQAAAbPAAAG4gAABvUAAAcSAAAHJwAAB0AAAAdTAAAHcAAAB4UAAAeeAAAHsQAAB8gAAAfjAAAH9gAACA8AAAgmAAAIQQAACFQAAAhnAAAIhAAACJcAAAMsdHJhawAAAFx0a2hkAAAAA9WAgl/VgIJfAAAAAgAAAAAAAAf8AAAAAAAAAAAAAAABAQAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAACsm1kaWEAAAAgbWRoZAAAAADVgIJf1YCCXwAArEQAAWAAVcQAAAAAACdoZGxyAAAAAAAAAABzb3VuAAAAAAAAAAAAAAAAU3RlcmVvAAAAAmNtaW5mAAAAEHNtaGQAAAAAAAAAAAAAACRkaW5mAAAAHGRyZWYAAAAAAAAAAQAAAAx1cmwgAAAAAQAAAidzdGJsAAAAZ3N0c2QAAAAAAAAAAQAAAFdtcDRhAAAAAAAAAAEAAAAAAAAAAAACABAAAAAArEQAAAAAADNlc2RzAAAAAAOAgIAiAAIABICAgBRAFQAAAAADDUAAAAAABYCAgAISEAaAgIABAgAAABhzdHRzAAAAAAAAAAEAAABYAAAEAAAAABxzdHNjAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAUc3RzegAAAAAAAAAGAAAAWAAAAXBzdGNvAAAAAAAAAFgAAAOBAAADhwAAA5oAAAOtAAADswAAA8oAAAPfAAAD5QAAA/gAAAQLAAAEEQAABCgAAAQ9AAAEUAAABFYAAARpAAAEgAAABIYAAASbAAAErgAABLQAAATHAAAE3gAABPMAAAT5AAAFDAAABR8AAAUlAAAFPAAABVEAAAVXAAAFagAABX0AAAWDAAAFmgAABa8AAAXCAAAFyAAABdsAAAXyAAAF+AAABg0AAAYgAAAGJgAABjkAAAZQAAAGZQAABmsAAAZ+AAAGkQAABpcAAAauAAAGwwAABskAAAbcAAAG7wAABwYAAAcMAAAHIQAABzQAAAc6AAAHTQAAB2QAAAdqAAAHfwAAB5IAAAeYAAAHqwAAB8IAAAfXAAAH3QAAB/AAAAgDAAAICQAACCAAAAg1AAAIOwAACE4AAAhhAAAIeAAACH4AAAiRAAAIpAAACKoAAAiwAAAItgAACLwAAAjCAAAAFnVkdGEAAAAObmFtZVN0ZXJlbwAAAHB1ZHRhAAAAaG1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAO2lsc3QAAAAzqXRvbwAAACtkYXRhAAAAAQAAAABIYW5kQnJha2UgMC4xMC4yIDIwMTUwNjExMDA=' 5 | 6 | var _createClass = (function () { 7 | function defineProperties(target, props) { 8 | for (var i = 0; i < props.length; i++) { 9 | var descriptor = props[i] 10 | descriptor.enumerable = descriptor.enumerable || false 11 | descriptor.configurable = true 12 | if ('value' in descriptor) descriptor.writable = true 13 | Object.defineProperty(target, descriptor.key, descriptor) 14 | } 15 | } 16 | return function (Constructor, protoProps, staticProps) { 17 | if (protoProps) defineProperties(Constructor.prototype, protoProps) 18 | if (staticProps) defineProperties(Constructor, staticProps) 19 | return Constructor 20 | } 21 | })() 22 | 23 | function _classCallCheck(instance, Constructor) { 24 | if (!(instance instanceof Constructor)) { 25 | throw new TypeError('Cannot call a class as a function') 26 | } 27 | } 28 | 29 | // Detect iOS browsers < version 10 30 | var oldIOS = 31 | typeof navigator !== 'undefined' && 32 | parseFloat( 33 | ( 34 | '' + 35 | (/CPU.*OS ([0-9_]{3,4})[0-9_]{0,1}|(CPU like).*AppleWebKit.*Mobile/i.exec( 36 | navigator.userAgent 37 | ) || [0, ''])[1] 38 | ) 39 | .replace('undefined', '3_2') 40 | .replace('_', '.') 41 | .replace('_', '') 42 | ) < 10 && 43 | !window.MSStream 44 | 45 | // Detect native Wake Lock API support 46 | var nativeWakeLock = 'wakeLock' in navigator 47 | 48 | var NoSleep = (function () { 49 | var _releasedNative = true 50 | var _nativeRequestInProgress = false 51 | 52 | function NoSleep() { 53 | var _this = this 54 | 55 | _classCallCheck(this, NoSleep) 56 | 57 | if (nativeWakeLock) { 58 | this._wakeLock = null 59 | var handleVisibilityChange = function handleVisibilityChange() { 60 | if ( 61 | _this._wakeLock !== null && 62 | document.visibilityState === 'visible' 63 | ) { 64 | _this.enable() 65 | } 66 | } 67 | document.addEventListener('visibilitychange', handleVisibilityChange) 68 | document.addEventListener('fullscreenchange', handleVisibilityChange) 69 | } else if (oldIOS) { 70 | this.noSleepTimer = null 71 | } else { 72 | // Set up no sleep video element 73 | this.noSleepVideo = document.createElement('video') 74 | 75 | this.noSleepVideo.setAttribute('title', 'No Sleep') 76 | this.noSleepVideo.setAttribute('playsinline', '') 77 | 78 | this._addSourceToVideo(this.noSleepVideo, 'webm', webm) 79 | this._addSourceToVideo(this.noSleepVideo, 'mp4', mp4) 80 | 81 | this.noSleepVideo.addEventListener('loadedmetadata', function () { 82 | if (_this.noSleepVideo.duration <= 1) { 83 | // webm source 84 | _this.noSleepVideo.setAttribute('loop', '') 85 | } else { 86 | // mp4 source 87 | _this.noSleepVideo.addEventListener('timeupdate', function () { 88 | if (_this.noSleepVideo.currentTime > 0.5) { 89 | _this.noSleepVideo.currentTime = Math.random() 90 | } 91 | }) 92 | } 93 | }) 94 | } 95 | } 96 | 97 | _createClass(NoSleep, [ 98 | { 99 | key: '_addSourceToVideo', 100 | value: function _addSourceToVideo(element, type, dataURI) { 101 | var source = document.createElement('source') 102 | source.src = dataURI 103 | source.type = 'video/' + type 104 | element.appendChild(source) 105 | }, 106 | }, 107 | { 108 | key: 'enable', 109 | value: function enable() { 110 | var _this2 = this 111 | 112 | if (nativeWakeLock) { 113 | _nativeRequestInProgress = true 114 | navigator.wakeLock 115 | .request('screen') 116 | .then(function (wakeLock) { 117 | _releasedNative = false 118 | _nativeRequestInProgress = false 119 | 120 | _this2._wakeLock = wakeLock 121 | _this2._wakeLock.addEventListener('release', function () { 122 | _releasedNative = true 123 | _this2._wakeLock = null 124 | }) 125 | }) 126 | .catch(function (err) { 127 | _nativeRequestInProgress = false 128 | console.error(err.name + ', ' + err.message) 129 | }) 130 | } else if (oldIOS) { 131 | this.disable() 132 | console.warn( 133 | '\n NoSleep enabled for older iOS devices. This can interrupt\n active or long-running network requests from completing successfully.\n See https://github.com/richtr/NoSleep.js/issues/15 for more details.\n ' 134 | ) 135 | this.noSleepTimer = window.setInterval(function () { 136 | if (!document.hidden) { 137 | window.location.href = window.location.href.split('#')[0] 138 | window.setTimeout(window.stop, 0) 139 | } 140 | }, 15000) 141 | } else { 142 | this.noSleepVideo.play() 143 | } 144 | }, 145 | }, 146 | { 147 | key: 'disable', 148 | value: function disable() { 149 | if (nativeWakeLock) { 150 | if (this._wakeLock != null) { 151 | _releasedNative = true 152 | this._wakeLock.release() 153 | } 154 | 155 | this._wakeLock = null 156 | } else if (oldIOS) { 157 | if (this.noSleepTimer) { 158 | console.warn( 159 | '\n NoSleep now disabled for older iOS devices.\n ' 160 | ) 161 | window.clearInterval(this.noSleepTimer) 162 | this.noSleepTimer = null 163 | } 164 | } else { 165 | this.noSleepVideo.pause() 166 | } 167 | }, 168 | }, 169 | { 170 | key: 'enabled', 171 | value: async function enabled() { 172 | if (nativeWakeLock) { 173 | if (_nativeRequestInProgress == true) { 174 | // Wait until the request is done. 175 | while (true) { 176 | // Wait for 42 milliseconds. 177 | await new Promise((resolve, reject) => setTimeout(resolve, 42)) 178 | if (_nativeRequestInProgress == false) { 179 | break 180 | } 181 | } 182 | } 183 | 184 | // todo: use WakeLockSentinel.released when that is available (https://developer.mozilla.org/en-US/docs/Web/API/WakeLockSentinel/released) 185 | if (_releasedNative != false) { 186 | return false 187 | } 188 | 189 | return true 190 | } else if (oldIOS) { 191 | return this.noSleepTimer != null 192 | } else { 193 | if (this.noSleepVideo == undefined) { 194 | return false 195 | } 196 | 197 | return !this.noSleepVideo.paused 198 | } 199 | }, 200 | }, 201 | ]) 202 | 203 | return NoSleep 204 | })() 205 | 206 | var noSleep = new NoSleep() 207 | 208 | var Wakelock = { 209 | enabled: async function () { 210 | try { 211 | return noSleep.enabled() 212 | } catch (e) { 213 | return false 214 | } 215 | }, 216 | toggle: async function (enable) { 217 | if (enable) { 218 | noSleep.enable() 219 | } else { 220 | noSleep.disable() 221 | } 222 | }, 223 | } 224 | 225 | if (nativeWakeLock != true) { 226 | // The first non-native call sometimes throws an error, however, 227 | // the error does not leak the try-catch above. Therefore, this 228 | // is an easy fix that realiably works. 229 | Wakelock.enabled() 230 | } 231 | -------------------------------------------------------------------------------- /web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/favicon.png -------------------------------------------------------------------------------- /web/flutter_service_worker.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const MANIFEST = 'flutter-app-manifest'; 3 | const TEMP = 'flutter-temp-cache'; 4 | const CACHE_NAME = 'flutter-app-cache'; 5 | const RESOURCES = { 6 | "version.json": "99efb6a1f1d0da42eda6b57b15b74c2a", 7 | "index.html": "e817555a30a7ab88be3f7b18185ef0d8", 8 | "/": "e817555a30a7ab88be3f7b18185ef0d8", 9 | "main.dart.js": "88286e80fbfc4e2e13da664afbe324ac", 10 | "favicon.png": "5dcef449791fa27946b3d35ad8803796", 11 | "icons/Icon-192.png": "ac9a721a12bbc803b44f645561ecb1e1", 12 | "icons/Icon-512.png": "96e752610906ba2a93c65f8abe1645f1", 13 | "manifest.json": "45db566f894ec8c66cca3db96105da10", 14 | "assets/AssetManifest.json": "b3bf1ea22cdeff988e121145fc468fd9", 15 | "assets/NOTICES": "ba37d6c1210d165dc2bf514312cbe0de", 16 | "assets/FontManifest.json": "5a32d4310a6f5d9a6b651e75ba0d7372", 17 | "assets/packages/cupertino_icons/assets/CupertinoIcons.ttf": "6d342eb68f170c97609e9da345464e5e", 18 | "assets/packages/font_awesome_flutter/lib/fonts/fa-solid-900.ttf": "dffd9504fcb1894620fa41c700172994", 19 | "assets/packages/font_awesome_flutter/lib/fonts/fa-regular-400.ttf": "4b6a9b7c20913279a3ad3dd9c96e155b", 20 | "assets/packages/font_awesome_flutter/lib/fonts/fa-brands-400.ttf": "00bb2b684be61e89d1bc7d75dee30b58", 21 | "assets/packages/wakelock_web/assets/no_sleep.js": "7748a45cd593f33280669b29c2c8919a", 22 | "assets/fonts/MaterialIcons-Regular.otf": "1288c9e28052e028aba623321f7826ac", 23 | "assets/assets/transparent.jpg": "f9bbe5edd9f243560b6db760e6ef9d68" 24 | }; 25 | 26 | // The application shell files that are downloaded before a service worker can 27 | // start. 28 | const CORE = [ 29 | "/", 30 | "main.dart.js", 31 | "index.html", 32 | "assets/NOTICES", 33 | "assets/AssetManifest.json", 34 | "assets/FontManifest.json"]; 35 | // During install, the TEMP cache is populated with the application shell files. 36 | self.addEventListener("install", (event) => { 37 | self.skipWaiting(); 38 | return event.waitUntil( 39 | caches.open(TEMP).then((cache) => { 40 | return cache.addAll( 41 | CORE.map((value) => new Request(value + '?revision=' + RESOURCES[value], {'cache': 'reload'}))); 42 | }) 43 | ); 44 | }); 45 | 46 | // During activate, the cache is populated with the temp files downloaded in 47 | // install. If this service worker is upgrading from one with a saved 48 | // MANIFEST, then use this to retain unchanged resource files. 49 | self.addEventListener("activate", function(event) { 50 | return event.waitUntil(async function() { 51 | try { 52 | var contentCache = await caches.open(CACHE_NAME); 53 | var tempCache = await caches.open(TEMP); 54 | var manifestCache = await caches.open(MANIFEST); 55 | var manifest = await manifestCache.match('manifest'); 56 | // When there is no prior manifest, clear the entire cache. 57 | if (!manifest) { 58 | await caches.delete(CACHE_NAME); 59 | contentCache = await caches.open(CACHE_NAME); 60 | for (var request of await tempCache.keys()) { 61 | var response = await tempCache.match(request); 62 | await contentCache.put(request, response); 63 | } 64 | await caches.delete(TEMP); 65 | // Save the manifest to make future upgrades efficient. 66 | await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES))); 67 | return; 68 | } 69 | var oldManifest = await manifest.json(); 70 | var origin = self.location.origin; 71 | for (var request of await contentCache.keys()) { 72 | var key = request.url.substring(origin.length + 1); 73 | if (key == "") { 74 | key = "/"; 75 | } 76 | // If a resource from the old manifest is not in the new cache, or if 77 | // the MD5 sum has changed, delete it. Otherwise the resource is left 78 | // in the cache and can be reused by the new service worker. 79 | if (!RESOURCES[key] || RESOURCES[key] != oldManifest[key]) { 80 | await contentCache.delete(request); 81 | } 82 | } 83 | // Populate the cache with the app shell TEMP files, potentially overwriting 84 | // cache files preserved above. 85 | for (var request of await tempCache.keys()) { 86 | var response = await tempCache.match(request); 87 | await contentCache.put(request, response); 88 | } 89 | await caches.delete(TEMP); 90 | // Save the manifest to make future upgrades efficient. 91 | await manifestCache.put('manifest', new Response(JSON.stringify(RESOURCES))); 92 | return; 93 | } catch (err) { 94 | // On an unhandled exception the state of the cache cannot be guaranteed. 95 | console.error('Failed to upgrade service worker: ' + err); 96 | await caches.delete(CACHE_NAME); 97 | await caches.delete(TEMP); 98 | await caches.delete(MANIFEST); 99 | } 100 | }()); 101 | }); 102 | 103 | // The fetch handler redirects requests for RESOURCE files to the service 104 | // worker cache. 105 | self.addEventListener("fetch", (event) => { 106 | if (event.request.method !== 'GET') { 107 | return; 108 | } 109 | var origin = self.location.origin; 110 | var key = event.request.url.substring(origin.length + 1); 111 | // Redirect URLs to the index.html 112 | if (key.indexOf('?v=') != -1) { 113 | key = key.split('?v=')[0]; 114 | } 115 | if (event.request.url == origin || event.request.url.startsWith(origin + '/#') || key == '') { 116 | key = '/'; 117 | } 118 | // If the URL is not the RESOURCE list then return to signal that the 119 | // browser should take over. 120 | if (!RESOURCES[key]) { 121 | return; 122 | } 123 | // If the URL is the index.html, perform an online-first request. 124 | if (key == '/') { 125 | return onlineFirst(event); 126 | } 127 | event.respondWith(caches.open(CACHE_NAME) 128 | .then((cache) => { 129 | return cache.match(event.request).then((response) => { 130 | // Either respond with the cached resource, or perform a fetch and 131 | // lazily populate the cache. 132 | return response || fetch(event.request).then((response) => { 133 | cache.put(event.request, response.clone()); 134 | return response; 135 | }); 136 | }) 137 | }) 138 | ); 139 | }); 140 | 141 | self.addEventListener('message', (event) => { 142 | // SkipWaiting can be used to immediately activate a waiting service worker. 143 | // This will also require a page refresh triggered by the main worker. 144 | if (event.data === 'skipWaiting') { 145 | self.skipWaiting(); 146 | return; 147 | } 148 | if (event.data === 'downloadOffline') { 149 | downloadOffline(); 150 | return; 151 | } 152 | }); 153 | 154 | // Download offline will check the RESOURCES for all files not in the cache 155 | // and populate them. 156 | async function downloadOffline() { 157 | var resources = []; 158 | var contentCache = await caches.open(CACHE_NAME); 159 | var currentContent = {}; 160 | for (var request of await contentCache.keys()) { 161 | var key = request.url.substring(origin.length + 1); 162 | if (key == "") { 163 | key = "/"; 164 | } 165 | currentContent[key] = true; 166 | } 167 | for (var resourceKey of Object.keys(RESOURCES)) { 168 | if (!currentContent[resourceKey]) { 169 | resources.push(resourceKey); 170 | } 171 | } 172 | return contentCache.addAll(resources); 173 | } 174 | 175 | // Attempt to download the resource online before falling back to 176 | // the offline cache. 177 | function onlineFirst(event) { 178 | return event.respondWith( 179 | fetch(event.request).then((response) => { 180 | return caches.open(CACHE_NAME).then((cache) => { 181 | cache.put(event.request, response.clone()); 182 | return response; 183 | }); 184 | }).catch((error) => { 185 | return caches.open(CACHE_NAME).then((cache) => { 186 | return cache.match(event.request).then((response) => { 187 | if (response != null) { 188 | return response; 189 | } 190 | throw error; 191 | }); 192 | }); 193 | }) 194 | ); 195 | } 196 | -------------------------------------------------------------------------------- /web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/icons/Icon-192.png -------------------------------------------------------------------------------- /web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ankiimation/ankii_flutter_gradient/d6d3e913bdb236b3c8718cc2f69810630e003a19/web/icons/Icon-512.png -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | ankii_flutter_gradient 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ankii_flutter_gradient", 3 | "short_name": "ankii_flutter_gradient", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /web/version.json: -------------------------------------------------------------------------------- 1 | {"app_name":"ankii_flutter_gradient","version":"1.0.0","build_number":"1"} --------------------------------------------------------------------------------