diff --git a/.gitignore b/.gitignore index e9dc58d..bdf834e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,63 @@ -.DS_Store +# https://www.dartlang.org/guides/libraries/private-files + +# Files and directories created by pub .dart_tool/ +.packages +.pub/ +build/ +pubspec.lock + +# Directory created by dartdoc +/doc/api/ + +# IDE +*.iml // IntelliJ +*.ipr // IntelliJ +*.iws // IntelliJ +.idea/ // IntelliJ +.DS_Store // Mac + +# copied from https://github.com/flutter/plugins/blob/master/.gitignore +.DS_Store +.atom/ +.idea/ +.vscode/ .packages .pub/ +.dart_tool/ +pubspec.lock +flutter_export_environment.sh + +examples/all_plugins/pubspec.yaml +Podfile +Podfile.lock +Pods/ +.symlinks/ +**/Flutter/App.framework/ +**/Flutter/Flutter.framework/ +**/Flutter/Generated.xcconfig +**/Flutter/flutter_assets/ +ServiceDefinitions.json +xcuserdata/ +**/DerivedData/ + +local.properties +keystore.properties +.gradle/ +gradlew +gradlew.bat +gradle-wrapper.jar +.flutter-plugins-dependencies +*.iml + +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.java build/ +.flutter-plugins + +.project +.classpath +.settings diff --git a/android/build.gradle b/android/build.gradle index b211d53..a7de000 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.library' apply plugin: 'kotlin-android' android { - compileSdkVersion 28 + compileSdkVersion 29 sourceSets { main.java.srcDirs += 'src/main/kotlin' diff --git a/android/gradle.properties b/android/gradle.properties index 8bd86f6..4d3226a 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1 +1,3 @@ org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/android/gradlew b/android/gradlew old mode 100644 new mode 100755 diff --git a/android/src/main/kotlin/com/kasem/flutter_absolute_path/FileDirectory.kt b/android/src/main/kotlin/com/kasem/flutter_absolute_path/FileDirectory.kt index 47b955b..f710866 100644 --- a/android/src/main/kotlin/com/kasem/flutter_absolute_path/FileDirectory.kt +++ b/android/src/main/kotlin/com/kasem/flutter_absolute_path/FileDirectory.kt @@ -10,6 +10,7 @@ import android.provider.DocumentsContract import android.provider.MediaStore import java.io.* import java.util.* +import java.io.File object FileDirectory { @@ -67,6 +68,12 @@ object FileDirectory { }// MediaProvider // DownloadsProvider } else if ("content".equals(uri.scheme, ignoreCase = true)) { + + // Return the remote address + // source: https://gist.github.com/chauhan-tarun/15eb908a778ac77835d7433e04f71c16 + if (isGooglePhotosUri(uri)) + return uri.getLastPathSegment(); + return getDataColumn(context, uri, null, null) } @@ -86,16 +93,6 @@ object FileDirectory { private fun getDataColumn(context: Context, uri: Uri, selection: String?, selectionArgs: Array?): String? { - if (uri.authority != null) { - val targetFile = File(context.cacheDir, "IMG_${Date().time}.png") - context.contentResolver.openInputStream(uri)?.use { input -> - FileOutputStream(targetFile).use { fileOut -> - input.copyTo(fileOut) - } - } - return targetFile.path - } - var cursor: Cursor? = null val column = "_data" val projection = arrayOf(column) @@ -136,4 +133,12 @@ object FileDirectory { fun isMediaDocument(uri: Uri): Boolean { return "com.android.providers.media.documents" == uri.authority } -} + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is Google Photos. + */ + fun isGooglePhotosUri(uri: Uri): Boolean { + return "com.google.android.apps.photos.content" == uri.authority + } +} \ No newline at end of file diff --git a/android/src/main/kotlin/com/kasem/flutter_absolute_path/FlutterAbsolutePathPlugin.kt b/android/src/main/kotlin/com/kasem/flutter_absolute_path/FlutterAbsolutePathPlugin.kt index 163edee..ab207e1 100644 --- a/android/src/main/kotlin/com/kasem/flutter_absolute_path/FlutterAbsolutePathPlugin.kt +++ b/android/src/main/kotlin/com/kasem/flutter_absolute_path/FlutterAbsolutePathPlugin.kt @@ -1,29 +1,60 @@ package com.kasem.flutter_absolute_path -import android.content.Context -import android.content.Intent -import android.net.Uri -import android.os.Environment +import androidx.annotation.NonNull; +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.embedding.engine.plugins.activity.ActivityAware +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import io.flutter.plugin.common.MethodCall import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel.MethodCallHandler import io.flutter.plugin.common.MethodChannel.Result import io.flutter.plugin.common.PluginRegistry.Registrar -import android.util.Log -import android.content.pm.ProviderInfo -import android.content.pm.PackageManager -import android.content.pm.PackageInfo -import java.security.Provider +import android.content.Context +import android.app.Activity +import android.net.Uri -class FlutterAbsolutePathPlugin(private val context: Context) : MethodCallHandler { +import io.flutter.plugin.common.BinaryMessenger - companion object { - @JvmStatic - fun registerWith(registrar: Registrar) { - val channel = MethodChannel(registrar.messenger(), "flutter_absolute_path") - channel.setMethodCallHandler(FlutterAbsolutePathPlugin(registrar.context())) - } +class FlutterAbsolutePathPlugin : FlutterPlugin, ActivityAware, MethodCallHandler{ + private lateinit var channel : MethodChannel + + private lateinit var context: Context + private lateinit var activity: Activity + + private var pluginBinding: FlutterPlugin.FlutterPluginBinding? = null + private var activityBinding: ActivityPluginBinding? = null + private var methodChannel: MethodChannel? = null + + override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "flutter_absolute_path") + channel.setMethodCallHandler(this); + context = flutterPluginBinding.applicationContext + + // From flutter file picker + pluginBinding = flutterPluginBinding + val messenger = pluginBinding?.binaryMessenger + doOnAttachedToEngine(messenger!!) + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + // TODO: your plugin is no longer attached to a Flutter experience. + } + + override fun onAttachedToActivity(binding: ActivityPluginBinding) { + activity = binding.activity; + + // From flutter file picker + doOnAttachedToActivity(binding) + } + + override fun onDetachedFromActivity() { + } + + override fun onDetachedFromActivityForConfigChanges() { + } + + override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { } override fun onMethodCall(call: MethodCall, result: Result) { @@ -31,25 +62,32 @@ class FlutterAbsolutePathPlugin(private val context: Context) : MethodCallHandle call.method == "getAbsolutePath" -> { val uriString = call.argument("uri") as String val uri = Uri.parse(uriString) - -// val provider = applicationProviders?.firstOrNull { uri.authority == it.authority } -// if (provider != null) { -// val folderPath = Environment.getExternalStorageDirectory().path + "/Pictures" -// result.success("$folderPath/${uri.lastPathSegment}") -// return -// } - result.success(FileDirectory.getAbsolutePath(this.context, uri)) } else -> result.notImplemented() } } -// val applicationProviders: List? by lazy { -// val applicationId = context.packageName -// context.packageManager -// .getInstalledPackages(PackageManager.GET_PROVIDERS) -// .firstOrNull { it.packageName == applicationId } -// ?.providers?.toList() -// } + // V1 only + private var registrar: Registrar? = null + companion object { + @JvmStatic + fun registerWith(registrar: Registrar) { + if (registrar.activity() != null) { + val plugin = FlutterAbsolutePathPlugin() + plugin.doOnAttachedToEngine(registrar.messenger()) + plugin.doOnAttachedToActivity(null, registrar) + } + } + } + private fun doOnAttachedToActivity(activityBinding: ActivityPluginBinding?, + registrar: Registrar? = null) { + this.activityBinding = activityBinding + this.registrar = registrar + } + private fun doOnAttachedToEngine(messenger: BinaryMessenger) { + methodChannel = MethodChannel(messenger, "flutter_absolute_path") + methodChannel?.setMethodCallHandler(this) + context = pluginBinding!!.applicationContext + } } diff --git a/example/.gitignore b/example/.gitignore index 07488ba..bdf834e 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -1,70 +1,63 @@ -# Miscellaneous -*.class -*.log -*.pyc -*.swp +# https://www.dartlang.org/guides/libraries/private-files + +# Files and directories created by pub +.dart_tool/ +.packages +.pub/ +build/ +pubspec.lock + +# Directory created by dartdoc +/doc/api/ + +# IDE +*.iml // IntelliJ +*.ipr // IntelliJ +*.iws // IntelliJ +.idea/ // IntelliJ +.DS_Store // Mac + +# copied from https://github.com/flutter/plugins/blob/master/.gitignore .DS_Store .atom/ -.buildlog/ -.history -.svn/ - -# IntelliJ related -*.iml -*.ipr -*.iws .idea/ - -# Visual Studio Code related .vscode/ -# Flutter/Dart/Pub related -**/doc/api/ -.dart_tool/ -.flutter-plugins .packages -.pub-cache/ .pub/ -/build/ +.dart_tool/ +pubspec.lock +flutter_export_environment.sh -# Android related -**/android/**/gradle-wrapper.jar -**/android/.gradle -**/android/captures/ -**/android/gradlew -**/android/gradlew.bat -**/android/local.properties -**/android/**/GeneratedPluginRegistrant.java +examples/all_plugins/pubspec.yaml -# iOS/XCode related -**/ios/**/*.mode1v3 -**/ios/**/*.mode2v3 -**/ios/**/*.moved-aside -**/ios/**/*.pbxuser -**/ios/**/*.perspectivev3 -**/ios/**/*sync/ -**/ios/**/.sconsign.dblite -**/ios/**/.tags* -**/ios/**/.vagrant/ -**/ios/**/DerivedData/ -**/ios/**/Icon? -**/ios/**/Pods/ -**/ios/**/.symlinks/ -**/ios/**/profile -**/ios/**/xcuserdata -**/ios/.generated/ -**/ios/Flutter/App.framework -**/ios/Flutter/Flutter.framework -**/ios/Flutter/Generated.xcconfig -**/ios/Flutter/app.flx -**/ios/Flutter/app.zip -**/ios/Flutter/flutter_assets/ -**/ios/ServiceDefinitions.json -**/ios/Runner/GeneratedPluginRegistrant.* +Podfile +Podfile.lock +Pods/ +.symlinks/ +**/Flutter/App.framework/ +**/Flutter/Flutter.framework/ +**/Flutter/Generated.xcconfig +**/Flutter/flutter_assets/ +ServiceDefinitions.json +xcuserdata/ +**/DerivedData/ + +local.properties +keystore.properties +.gradle/ +gradlew +gradlew.bat +gradle-wrapper.jar +.flutter-plugins-dependencies +*.iml + +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m +GeneratedPluginRegistrant.java +build/ +.flutter-plugins -# Exceptions to above rules. -!**/ios/**/default.mode1v3 -!**/ios/**/default.mode2v3 -!**/ios/**/default.pbxuser -!**/ios/**/default.perspectivev3 -!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +.project +.classpath +.settings diff --git a/example/android/app/build.gradle b/example/android/app/build.gradle index 782ae58..71e33f3 100644 --- a/example/android/app/build.gradle +++ b/example/android/app/build.gradle @@ -26,7 +26,7 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 29 sourceSets { main.java.srcDirs += 'src/main/kotlin' @@ -39,8 +39,8 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.kasem.flutter_absolute_path_example" - minSdkVersion 16 - targetSdkVersion 28 + minSdkVersion 19 + targetSdkVersion 29 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" diff --git a/example/android/app/src/main/AndroidManifest.xml b/example/android/app/src/main/AndroidManifest.xml index 5bf86b4..88434af 100644 --- a/example/android/app/src/main/AndroidManifest.xml +++ b/example/android/app/src/main/AndroidManifest.xml @@ -1,15 +1,20 @@ + + + + + + android:icon="@mipmap/ic_launcher" + android:requestLegacyExternalStorage="true"> + android:name="flutterEmbedding" + android:value="2" /> diff --git a/example/android/app/src/main/kotlin/com/kasem/flutter_absolute_path_example/MainActivity.kt b/example/android/app/src/main/kotlin/com/kasem/flutter_absolute_path_example/MainActivity.kt index 81e35f9..a3c0ada 100644 --- a/example/android/app/src/main/kotlin/com/kasem/flutter_absolute_path_example/MainActivity.kt +++ b/example/android/app/src/main/kotlin/com/kasem/flutter_absolute_path_example/MainActivity.kt @@ -1,13 +1,6 @@ package com.kasem.flutter_absolute_path_example -import android.os.Bundle - -import io.flutter.app.FlutterActivity -import io.flutter.plugins.GeneratedPluginRegistrant +import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - GeneratedPluginRegistrant.registerWith(this) - } } diff --git a/example/android/gradle.properties b/example/android/gradle.properties index 8bd86f6..4d3226a 100644 --- a/example/android/gradle.properties +++ b/example/android/gradle.properties @@ -1 +1,3 @@ org.gradle.jvmargs=-Xmx1536M +android.useAndroidX=true +android.enableJetifier=true \ No newline at end of file diff --git a/example/ios/Podfile b/example/ios/Podfile deleted file mode 100644 index 64eddc6..0000000 --- a/example/ios/Podfile +++ /dev/null @@ -1,71 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '9.0' - -# CocoaPods analytics sends network stats synchronously affecting flutter build latency. -ENV['COCOAPODS_DISABLE_STATS'] = 'true' - -project 'Runner', { - 'Debug' => :debug, - 'Profile' => :release, - 'Release' => :release, -} - -def parse_KV_file(file, separator='=') - file_abs_path = File.expand_path(file) - if !File.exists? file_abs_path - return []; - end - pods_ary = [] - skip_line_start_symbols = ["#", "/"] - File.foreach(file_abs_path) { |line| - next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ } - plugin = line.split(pattern=separator) - if plugin.length == 2 - podname = plugin[0].strip() - path = plugin[1].strip() - podpath = File.expand_path("#{path}", file_abs_path) - pods_ary.push({:name => podname, :path => podpath}); - else - puts "Invalid plugin specification: #{line}" - end - } - return pods_ary -end - -target 'Runner' do - use_frameworks! - - # Prepare symlinks folder. We use symlinks to avoid having Podfile.lock - # referring to absolute paths on developers' machines. - system('rm -rf .symlinks') - system('mkdir -p .symlinks/plugins') - - # Flutter Pods - generated_xcode_build_settings = parse_KV_file('./Flutter/Generated.xcconfig') - if generated_xcode_build_settings.empty? - puts "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter packages get is executed first." - end - generated_xcode_build_settings.map { |p| - if p[:name] == 'FLUTTER_FRAMEWORK_DIR' - symlink = File.join('.symlinks', 'flutter') - File.symlink(File.dirname(p[:path]), symlink) - pod 'Flutter', :path => File.join(symlink, File.basename(p[:path])) - end - } - - # Plugin Pods - plugin_pods = parse_KV_file('../.flutter-plugins') - plugin_pods.map { |p| - symlink = File.join('.symlinks', 'plugins', p[:name]) - File.symlink(p[:path], symlink) - pod p[:name], :path => File.join(symlink, 'ios') - } -end - -post_install do |installer| - installer.pods_project.targets.each do |target| - target.build_configurations.each do |config| - config.build_settings['ENABLE_BITCODE'] = 'NO' - end - end -end diff --git a/example/lib/main.dart b/example/lib/main.dart index ecded0f..2d7dc04 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -31,7 +31,7 @@ class _MyAppState extends State { List files = []; for (Asset asset in assets) { final filePath = - await FlutterAbsolutePath.getAbsolutePath(asset.identifier); + await FlutterAbsolutePath.getAbsolutePath(asset.identifier); files.add(File(filePath)); } diff --git a/example/pubspec.lock b/example/pubspec.lock index a720e8a..23c6087 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://www.dartlang.org/tools/pub/glossary#lockfile +# See https://dart.dev/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,28 +7,42 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.2.0" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.15.0" cupertino_icons: dependency: "direct main" description: @@ -36,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -47,7 +68,7 @@ packages: path: ".." relative: true source: path - version: "1.0.4" + version: "1.0.6" flutter_test: dependency: "direct dev" description: flutter @@ -59,42 +80,28 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.5" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" multi_image_picker: dependency: "direct main" description: name: multi_image_picker url: "https://pub.dartlang.org" source: hosted - version: "4.1.2" + version: "4.8.01" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.2" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" + version: "1.8.0" sky_engine: dependency: transitive description: flutter @@ -106,56 +113,56 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.4" + version: "0.2.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" sdks: - dart: ">=2.2.0 <3.0.0" - flutter: ">=0.1.4 <2.0.0" + dart: ">=2.12.0 <3.0.0" + flutter: ">=1.12.13" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index f70fc61..3aeb2c4 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -12,7 +12,7 @@ dependencies: # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2 - multi_image_picker: 4.1.2 + multi_image_picker: 4.8.1 dev_dependencies: flutter_test: diff --git a/pubspec.lock b/pubspec.lock index a1e8431..19b13d0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,5 +1,5 @@ # Generated by pub -# See https://www.dartlang.org/tools/pub/glossary#lockfile +# See https://dart.dev/tools/pub/glossary#lockfile packages: async: dependency: transitive @@ -7,28 +7,49 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.5.0" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "2.1.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.2.0" + clock: + dependency: transitive + description: + name: clock + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.11" + version: "1.15.0" + fake_async: + dependency: transitive + description: + name: fake_async + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" flutter: dependency: "direct main" description: flutter @@ -45,35 +66,21 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.5" + version: "0.12.10" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" path: dependency: transitive description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.2" - pedantic: - dependency: transitive - description: - name: pedantic - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.0" - quiver: - dependency: transitive - description: - name: quiver - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.2" + version: "1.8.0" sky_engine: dependency: transitive description: flutter @@ -85,55 +92,55 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.5.5" + version: "1.8.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.10.0" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.1.0" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.4" + version: "0.2.19" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0" vector_math: dependency: transitive description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0" sdks: - dart: ">=2.2.0 <3.0.0" + dart: ">=2.12.0-0.0 <3.0.0"