add new dependency
This commit is contained in:
parent
83475a9128
commit
9d1f1bc4ed
37 changed files with 2263 additions and 2003 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
.venv
|
||||
.dart_tool
|
||||
.dart_tool
|
||||
.flutter-plugins-dependencies
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
adaptive_number: ea9178fdd4d82ac45cf0ec966ac870dae661124f
|
||||
dots_indicator: 508f5883ac79bdbc10254092de3f28f571d261cd
|
||||
ed25519_edwards: 7353ba759ea9f4646cbf481c2ef949625c8ce4cf
|
||||
flutter_sharing_intent: aa1672f547d6579585fa27df0b28ffa2a2544aaa
|
||||
hand_signature: 1beedb164d093643365b0832277c377353c7464f
|
||||
hashlib: 983cdbd5ee2529b908876b57a7217c09c6bc148a
|
||||
hashlib_codecs: 2a966c37c3b9b1f5541ae88e99ab34acf3fc968b
|
||||
|
|
|
|||
|
|
@ -46,4 +46,7 @@ libsignal_protocol_dart:
|
|||
git: https://github.com/Tougee/curve25519.git
|
||||
|
||||
hand_signature:
|
||||
git: https://github.com/RomanBase/hand_signature.git
|
||||
git: https://github.com/RomanBase/hand_signature.git
|
||||
|
||||
flutter_sharing_intent:
|
||||
git: https://github.com/bhagat-techind/flutter_sharing_intent.git
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.1.1"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
sdks:
|
||||
dart: ">=3.8.0-0 <4.0.0"
|
||||
201
flutter_sharing_intent/LICENSE
Normal file
201
flutter_sharing_intent/LICENSE
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
9
flutter_sharing_intent/android/.gitignore
vendored
Normal file
9
flutter_sharing_intent/android/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/workspace.xml
|
||||
/.idea/libraries
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.cxx
|
||||
53
flutter_sharing_intent/android/build.gradle
Normal file
53
flutter_sharing_intent/android/build.gradle
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
group 'com.techind.flutter_sharing_intent'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '2.1.20'
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.3.0'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
namespace 'com.techind.flutter_sharing_intent'
|
||||
compileSdkVersion 36
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 21
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
}
|
||||
1
flutter_sharing_intent/android/settings.gradle
Normal file
1
flutter_sharing_intent/android/settings.gradle
Normal file
|
|
@ -0,0 +1 @@
|
|||
rootProject.name = 'flutter_sharing_intent'
|
||||
72
flutter_sharing_intent/android/src/main/AndroidManifest.xml
Normal file
72
flutter_sharing_intent/android/src/main/AndroidManifest.xml
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.techind.flutter_sharing_intent">
|
||||
|
||||
<!-- <application>-->
|
||||
<!-- <activity-->
|
||||
<!-- android:name=".MainActivity"-->
|
||||
<!-- android:configChanges="orientation|keyboardHidden|screenSize"-->
|
||||
<!-- android:exported="true"-->
|
||||
<!-- android:theme="@style/LaunchTheme"-->
|
||||
<!-- android:hardwareAccelerated="true"-->
|
||||
<!-- android:windowSoftInputMode="adjustResize"-->
|
||||
<!-- android:screenOrientation="portrait"-->
|
||||
<!-- android:launchMode="singleTask">-->
|
||||
|
||||
<!-- <!–TODO: Add this filter, if you want to support sharing text into your app–>-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.SEND" />-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <data android:mimeType="text/*" />-->
|
||||
<!-- </intent-filter>-->
|
||||
|
||||
<!-- <!–TODO: Add this filter, if you want to support sharing images into your app–>-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.SEND" />-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <data android:mimeType="image/*" />-->
|
||||
<!-- </intent-filter>-->
|
||||
|
||||
<!-- <!–TODO: Add this filter, if you want to support sharing multi images into your app–>-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.SEND_MULTIPLE" />-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <data android:mimeType="image/*" />-->
|
||||
<!-- </intent-filter>-->
|
||||
|
||||
<!-- <!–TODO: Add this filter, if you want to support sharing videos into your app–>-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.SEND" />-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <data android:mimeType="video/*" />-->
|
||||
<!-- </intent-filter>-->
|
||||
|
||||
<!-- <!–TODO: Add this filter, if you want to support sharing multi videos into your app–>-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.SEND_MULTIPLE" />-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <data android:mimeType="video/*" />-->
|
||||
<!-- </intent-filter>-->
|
||||
|
||||
|
||||
<!-- <!–TODO: Add this filter, if you want to support sharing any type of files–>-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.SEND" />-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <data android:mimeType="*/*" />-->
|
||||
<!-- </intent-filter>-->
|
||||
|
||||
<!-- <!–TODO: Add this filter, if you want to support sharing multiple files of any type–>-->
|
||||
<!-- <intent-filter>-->
|
||||
<!-- <action android:name="android.intent.action.SEND_MULTIPLE" />-->
|
||||
<!-- <category android:name="android.intent.category.DEFAULT" />-->
|
||||
<!-- <data android:mimeType="*/*" />-->
|
||||
<!-- </intent-filter>-->
|
||||
|
||||
<!-- <meta-data-->
|
||||
<!-- android:name="android.app.lib_name"-->
|
||||
<!-- android:value="" />-->
|
||||
<!-- </activity>-->
|
||||
<!-- </application>-->
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,314 @@
|
|||
package com.techind.flutter_sharing_intent
|
||||
|
||||
import android.app.SearchManager
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.media.MediaMetadataRetriever
|
||||
import android.media.ThumbnailUtils
|
||||
import android.net.Uri
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.webkit.URLUtil
|
||||
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.*
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||
import io.flutter.plugin.common.MethodChannel.Result
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.net.URLConnection
|
||||
|
||||
private const val EVENTS_CHANNEL_MEDIA = "flutter_sharing_intent/events-sharing"
|
||||
|
||||
/**
|
||||
** Author - Bhagat Singh
|
||||
** Contact - https://www.linkedin.com/in/bhagat-singh-79496a14b/
|
||||
** Created On - 25/11/2022
|
||||
** Purpose - Created [FlutterSharingIntentPlugin] class to manage sharing intent
|
||||
*/
|
||||
|
||||
class FlutterSharingIntentPlugin: FlutterPlugin, ActivityAware, MethodCallHandler,
|
||||
EventChannel.StreamHandler,
|
||||
PluginRegistry.NewIntentListener {
|
||||
private var TAG:String = javaClass.name
|
||||
|
||||
/** To store initial & latest value when app is opened from background **/
|
||||
private var initialSharing: JSONArray? = null
|
||||
private var latestSharing: JSONArray? = null
|
||||
|
||||
/// The MethodChannel that will the communication between Flutter and native Android
|
||||
private lateinit var channel : MethodChannel
|
||||
private lateinit var eventChannel: EventChannel
|
||||
|
||||
private var eventSinkSharing: EventChannel.EventSink? = null
|
||||
|
||||
private var binding: ActivityPluginBinding? = null
|
||||
private lateinit var applicationContext: Context
|
||||
|
||||
/// To sel channel & event stream
|
||||
private fun setupCallbackChannels(binaryMessenger: BinaryMessenger) {
|
||||
channel = MethodChannel(binaryMessenger, "flutter_sharing_intent")
|
||||
channel.setMethodCallHandler(this)
|
||||
|
||||
eventChannel = EventChannel(binaryMessenger, EVENTS_CHANNEL_MEDIA)
|
||||
eventChannel.setStreamHandler(this)
|
||||
|
||||
}
|
||||
|
||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||
applicationContext = flutterPluginBinding.applicationContext
|
||||
setupCallbackChannels(flutterPluginBinding.binaryMessenger)
|
||||
}
|
||||
|
||||
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||
when (call.method) {
|
||||
"getInitialSharing" -> {
|
||||
result.success(initialSharing?.toString())
|
||||
/// Clear cache data to send only once
|
||||
initialSharing = null
|
||||
latestSharing = null
|
||||
}
|
||||
"reset" -> {
|
||||
initialSharing = null
|
||||
latestSharing = null
|
||||
result.success(null)
|
||||
}
|
||||
else -> result.notImplemented()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
||||
channel.setMethodCallHandler(null)
|
||||
initialSharing = null
|
||||
latestSharing = null
|
||||
eventChannel.setStreamHandler(null)
|
||||
}
|
||||
|
||||
private fun handleIntent(intent: Intent, initial: Boolean) {
|
||||
val intentFlags = intent.getFlags()
|
||||
if ((intentFlags and Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) == 0){
|
||||
Log.w(TAG,"handleIntent ==>> ${intent.action}, ${intent.type}")
|
||||
when {
|
||||
(intent.type?.startsWith("text") != true)
|
||||
&& (intent.action == Intent.ACTION_SEND
|
||||
|| intent.action == Intent.ACTION_SEND_MULTIPLE) -> { // Sharing images or videos
|
||||
|
||||
|
||||
val value = getSharingUris(intent)
|
||||
if (initial) initialSharing = value
|
||||
latestSharing = value
|
||||
Log.w(TAG,"Image/Video : handleIntent ==>> $value")
|
||||
eventSinkSharing?.success(value?.toString())
|
||||
}
|
||||
(intent.type == null || intent.type?.startsWith("text") == true)
|
||||
&& (intent.action == Intent.ACTION_SEND || intent.action == Intent.ACTION_SEND_MULTIPLE) -> { // Sharing text
|
||||
|
||||
val value = getSharingText(intent) ?: getSharingUris(intent)
|
||||
if (initial) initialSharing = value
|
||||
latestSharing = value
|
||||
Log.w(TAG,"text : handleIntent ==>> $value")
|
||||
// Log.w(TAG,"text : handleIntent ==>> ${eventSinkSharing!=null}")
|
||||
eventSinkSharing?.success(value?.toString())
|
||||
|
||||
}
|
||||
intent.action == Intent.ACTION_VIEW -> { // Opening URL
|
||||
val value = JSONArray().put(
|
||||
JSONObject()
|
||||
.put("value", intent.dataString)
|
||||
.put("type", MediaType.URL.ordinal)
|
||||
)
|
||||
if (initial) initialSharing = value
|
||||
latestSharing = value
|
||||
Log.w(TAG,"ACTION_VIEW : handleIntent ==>> $value")
|
||||
eventSinkSharing?.success(value?.toString())
|
||||
}
|
||||
intent.action == Intent.ACTION_WEB_SEARCH -> {
|
||||
val value = JSONArray().put(
|
||||
JSONObject()
|
||||
.put("value", intent.getStringExtra(SearchManager.QUERY))
|
||||
.put("type", MediaType.WEB_SEARCH.ordinal)
|
||||
)
|
||||
if (initial) initialSharing = value
|
||||
latestSharing = value
|
||||
Log.w(TAG,"ACTION_WEB_SEARCH : handleIntent ==>> $value")
|
||||
eventSinkSharing?.success(value?.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSharingUris(intent: Intent?): JSONArray? {
|
||||
if (intent == null) return null
|
||||
|
||||
return when (intent.action) {
|
||||
Intent.ACTION_SEND -> {
|
||||
val uri = intent.getParcelableExtra<Uri>(Intent.EXTRA_STREAM)
|
||||
val path = uri?.let{ MyFileDirectory.getAbsolutePath(applicationContext, it) }
|
||||
if (path != null) {
|
||||
val type = getMediaType(path)
|
||||
val thumbnail = getThumbnail(path, type)
|
||||
val duration = getDuration(path, type)
|
||||
|
||||
JSONArray().put(
|
||||
JSONObject()
|
||||
.put("value", path)
|
||||
.put("type", type.ordinal)
|
||||
.put("thumbnail", thumbnail)
|
||||
.put("duration", duration)
|
||||
)
|
||||
} else null
|
||||
}
|
||||
Intent.ACTION_SEND_MULTIPLE -> {
|
||||
val uris = intent.getParcelableArrayListExtra<Uri>(Intent.EXTRA_STREAM)
|
||||
val value = uris?.mapNotNull { uri ->
|
||||
val path = MyFileDirectory.getAbsolutePath(applicationContext, uri)
|
||||
?: return@mapNotNull null
|
||||
val type = getMediaType(path)
|
||||
val thumbnail = getThumbnail(path, type)
|
||||
val duration = getDuration(path, type)
|
||||
return@mapNotNull JSONObject()
|
||||
.put("value", path)
|
||||
.put("type", type.ordinal)
|
||||
.put("thumbnail", thumbnail)
|
||||
.put("duration", duration)
|
||||
}?.toList()
|
||||
if (value != null) JSONArray(value) else null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getSharingText(intent: Intent?): JSONArray? {
|
||||
if (intent == null) return null
|
||||
|
||||
return when (intent.action) {
|
||||
Intent.ACTION_SEND -> {
|
||||
val text = intent.getStringExtra(Intent.EXTRA_TEXT)
|
||||
if (text != null) {
|
||||
val type = getTypeForTextAndUrl(text)
|
||||
JSONArray().put(
|
||||
JSONObject()
|
||||
.put("value", text)
|
||||
.put("type", type)
|
||||
)
|
||||
} else null
|
||||
}
|
||||
Intent.ACTION_SEND_MULTIPLE -> {
|
||||
val textList = intent.getStringArrayListExtra(Intent.EXTRA_TEXT)
|
||||
|
||||
val value = textList?.mapNotNull { text ->
|
||||
val path = text
|
||||
?: return@mapNotNull null
|
||||
val type = getTypeForTextAndUrl(path)
|
||||
|
||||
return@mapNotNull JSONObject()
|
||||
.put("value", path)
|
||||
.put("type", type)
|
||||
}?.toList()
|
||||
if (value != null) JSONArray(value) else null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
// To get type for text and url only
|
||||
// It will return MediaType.URL.ordinal if text is valid url other will return MediaType.TEXT.ordinal
|
||||
fun getTypeForTextAndUrl( value: String?) : Int
|
||||
{
|
||||
return if (value == null || !URLUtil.isValidUrl(value)) MediaType.TEXT.ordinal else MediaType.URL.ordinal;
|
||||
}
|
||||
|
||||
private fun getMediaType(path: String?): MediaType {
|
||||
val mimeType = URLConnection.guessContentTypeFromName(path)
|
||||
return when {
|
||||
mimeType?.startsWith("image") == true -> MediaType.IMAGE
|
||||
mimeType?.startsWith("video") == true -> MediaType.VIDEO
|
||||
mimeType?.startsWith("text") == true -> MediaType.TEXT
|
||||
mimeType?.startsWith("url") == true -> MediaType.URL
|
||||
mimeType?.startsWith("web_search") == true -> MediaType.WEB_SEARCH
|
||||
else -> MediaType.FILE
|
||||
}
|
||||
}
|
||||
|
||||
private fun getThumbnail(path: String, type: MediaType): String? {
|
||||
if (type != MediaType.VIDEO) return null // get video thumbnail only
|
||||
|
||||
val videoFile = File(path)
|
||||
val targetFile = File(applicationContext.cacheDir, "${videoFile.name}.png")
|
||||
val bitmap = ThumbnailUtils.createVideoThumbnail(path, MediaStore.Video.Thumbnails.MINI_KIND)
|
||||
?: return null
|
||||
FileOutputStream(targetFile).use { out ->
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out)
|
||||
}
|
||||
bitmap.recycle()
|
||||
return targetFile.path
|
||||
}
|
||||
|
||||
private fun getDuration(path: String, type: MediaType): Long? {
|
||||
if (type != MediaType.VIDEO) return null // get duration for video only
|
||||
val retriever = MediaMetadataRetriever()
|
||||
retriever.setDataSource(path)
|
||||
val duration = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)?.toLongOrNull()
|
||||
retriever.release()
|
||||
return duration
|
||||
}
|
||||
|
||||
enum class MediaType {
|
||||
TEXT, URL, IMAGE, VIDEO, FILE, WEB_SEARCH ;
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent): Boolean {
|
||||
handleIntent(intent, false)
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
||||
this.binding = binding
|
||||
binding.addOnNewIntentListener(this)
|
||||
handleIntent(binding.activity.intent, true)
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivityForConfigChanges() {
|
||||
binding?.removeOnNewIntentListener(this)
|
||||
}
|
||||
|
||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
||||
this.binding = binding
|
||||
binding.addOnNewIntentListener(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromActivity() {
|
||||
binding?.removeOnNewIntentListener(this)
|
||||
}
|
||||
|
||||
override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {
|
||||
Log.d(TAG,"onListen ==>> $arguments, $events")
|
||||
when (arguments) {
|
||||
// "sharing" -> eventSinkSharing = events
|
||||
"sharing" -> {
|
||||
eventSinkSharing = events
|
||||
|
||||
|
||||
latestSharing?.let {
|
||||
Log.d(TAG, "Sending cached sharing data onListen: $it")
|
||||
// eventSinkSharing?.success(it.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancel(arguments: Any?) {
|
||||
Log.d(TAG,"onCancel ==>> $arguments")
|
||||
when (arguments) {
|
||||
"sharing" -> eventSinkSharing = null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,177 @@
|
|||
package com.techind.flutter_sharing_intent
|
||||
|
||||
import android.content.ContentUris
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Environment
|
||||
import android.provider.DocumentsContract
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.webkit.MimeTypeMap
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
** Author - Bhagat Singh
|
||||
** Contact - https://www.linkedin.com/in/bhagat-singh-79496a14b/
|
||||
** Created On - 25/11/2022
|
||||
** Purpose - Created [MyFileDirectory] to get path of a file
|
||||
*/
|
||||
|
||||
object MyFileDirectory {
|
||||
|
||||
/**
|
||||
* Get a file path from a Uri. This will get the the path for Storage Access
|
||||
* Framework Documents, as well as the _data field for the MediaStore and
|
||||
* other file-based ContentProviders.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param uri The Uri to query.
|
||||
* @author paulburke
|
||||
*/
|
||||
fun getAbsolutePath(context: Context, uri: Uri): String? {
|
||||
|
||||
// DocumentProvider
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
// ExternalStorageProvider
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
val docId = DocumentsContract.getDocumentId(uri)
|
||||
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
val type = split[0]
|
||||
|
||||
return if ("primary".equals(type, ignoreCase = true)) {
|
||||
Environment.getExternalStorageDirectory().toString() + "/" + split[1]
|
||||
} else {
|
||||
getDataColumn(context, uri, null, null)
|
||||
}
|
||||
} else if (isDownloadsDocument(uri)) {
|
||||
return try {
|
||||
val id = DocumentsContract.getDocumentId(uri)
|
||||
val contentUri = ContentUris.withAppendedId(
|
||||
Uri.parse("content://downloads/public_downloads"), java.lang.Long.valueOf(id))
|
||||
|
||||
getDataColumn(context, contentUri, null, null)
|
||||
} catch (exception: Exception) {
|
||||
getDataColumn(context, uri, null, null)
|
||||
}
|
||||
} else if (isMediaDocument(uri)) {
|
||||
val docId = DocumentsContract.getDocumentId(uri)
|
||||
val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
val type = split[0]
|
||||
|
||||
var contentUri: Uri? = null
|
||||
when (type) {
|
||||
"image" -> contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
||||
"video" -> contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
||||
"audio" -> contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
||||
}
|
||||
|
||||
if (contentUri == null) return null
|
||||
|
||||
val selection = "_id=?"
|
||||
val selectionArgs = arrayOf(split[1])
|
||||
return getDataColumn(context, contentUri, selection, selectionArgs)
|
||||
}// MediaProvider
|
||||
// DownloadsProvider
|
||||
} else if ("content".equals(uri.scheme, ignoreCase = true)) {
|
||||
return getDataColumn(context, uri, null, null)
|
||||
}
|
||||
|
||||
return uri.path
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value of the data column for this Uri. This is useful for
|
||||
* MediaStore Uris, and other file-based ContentProviders.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param uri The Uri to query.
|
||||
* @param selection (Optional) Filter used in the query.
|
||||
* @param selectionArgs (Optional) Selection arguments used in the query.
|
||||
* @return The value of the _data column, which is typically a file path.
|
||||
*/
|
||||
private fun getDataColumn(context: Context, uri: Uri, selection: String?,
|
||||
selectionArgs: Array<String>?): String? {
|
||||
|
||||
if (uri.authority != null) {
|
||||
var cursor: Cursor? = null
|
||||
val column = "_display_name"
|
||||
val projection = arrayOf(column)
|
||||
var targetFile: File? = null
|
||||
try {
|
||||
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
val columnIndex = cursor.getColumnIndexOrThrow(column)
|
||||
val fileName = cursor.getString(columnIndex)
|
||||
Log.i("FileDirectory", "File name: $fileName")
|
||||
targetFile = File(context.cacheDir, fileName)
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
|
||||
if (targetFile == null) {
|
||||
val mimeType = context.contentResolver.getType(uri)
|
||||
val prefix = with(mimeType ?: "") {
|
||||
when {
|
||||
startsWith("image") -> "IMG"
|
||||
startsWith("video") -> "VID"
|
||||
else -> "FILE"
|
||||
}
|
||||
}
|
||||
val type = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType)
|
||||
targetFile = File(context.cacheDir, "${prefix}_${Date().time}.$type")
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
try {
|
||||
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
val columnIndex = cursor.getColumnIndexOrThrow(column)
|
||||
return cursor.getString(columnIndex)
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is ExternalStorageProvider.
|
||||
*/
|
||||
private fun isExternalStorageDocument(uri: Uri): Boolean {
|
||||
return "com.android.externalstorage.documents" == uri.authority
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is DownloadsProvider.
|
||||
*/
|
||||
private fun isDownloadsDocument(uri: Uri): Boolean {
|
||||
return "com.android.providers.downloads.documents" == uri.authority
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri The Uri to check.
|
||||
* @return Whether the Uri authority is MediaProvider.
|
||||
*/
|
||||
private fun isMediaDocument(uri: Uri): Boolean {
|
||||
return "com.android.providers.media.documents" == uri.authority
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -0,0 +1 @@
|
|||
<resources></resources>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
|
||||
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<!-- Show a splash screen on the activity. Automatically removed when
|
||||
the Flutter engine draws its first frame -->
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
<!-- Theme applied to the Android Window as soon as the process has started.
|
||||
This theme determines the color of the Android Window while your
|
||||
Flutter UI initializes, as well as behind your Flutter UI while its
|
||||
running.
|
||||
|
||||
This Theme is only used starting with V2 of Flutter's Android embedding. -->
|
||||
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
|
||||
<item name="android:windowBackground">?android:colorBackground</item>
|
||||
</style>
|
||||
</resources>
|
||||
58
flutter_sharing_intent/ios/.gitignore
vendored
Normal file
58
flutter_sharing_intent/ios/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
.idea/
|
||||
.vagrant/
|
||||
.sconsign.dblite
|
||||
.svn/
|
||||
|
||||
.DS_Store
|
||||
*.swp
|
||||
profile
|
||||
|
||||
DerivedData/
|
||||
build/
|
||||
GeneratedPluginRegistrant.h
|
||||
GeneratedPluginRegistrant.m
|
||||
|
||||
.generated/
|
||||
|
||||
*.pbxuser
|
||||
*.mode1v3
|
||||
*.mode2v3
|
||||
*.perspectivev3
|
||||
|
||||
!default.pbxuser
|
||||
!default.mode1v3
|
||||
!default.mode2v3
|
||||
!default.perspectivev3
|
||||
|
||||
xcuserdata
|
||||
|
||||
*.moved-aside
|
||||
|
||||
*.pyc
|
||||
*sync/
|
||||
Icon?
|
||||
.tags*
|
||||
|
||||
/Flutter/Generated.xcconfig
|
||||
/Flutter/ephemeral/
|
||||
/Flutter/flutter_export_environment.sh
|
||||
Podfile.lock
|
||||
|
||||
**/dgph
|
||||
**/*sync/
|
||||
**/.vagrant/
|
||||
**/DerivedData/
|
||||
**/Pods/
|
||||
**/.symlinks/
|
||||
**/.generated/
|
||||
Flutter/App.framework
|
||||
Flutter/Flutter.framework
|
||||
Flutter/Flutter.podspec
|
||||
Flutter/Generated.xcconfig
|
||||
Flutter/ephemeral/
|
||||
Flutter/app.flx
|
||||
Flutter/app.zip
|
||||
Flutter/flutter_assets/
|
||||
Flutter/flutter_export_environment.sh
|
||||
ServiceDefinitions.json
|
||||
Runner/GeneratedPluginRegistrant.*
|
||||
0
flutter_sharing_intent/ios/Assets/.gitkeep
Normal file
0
flutter_sharing_intent/ios/Assets/.gitkeep
Normal file
599
flutter_sharing_intent/ios/Classes/FSIShareViewController.swift
Normal file
599
flutter_sharing_intent/ios/Classes/FSIShareViewController.swift
Normal file
|
|
@ -0,0 +1,599 @@
|
|||
// FSIShareViewController.swift
|
||||
// Merged, optimized controller: uses RSI architecture with all FSI features preserved
|
||||
// Uses model name `SharingFile` (same fields as SharedMediaFile) where `value` = path
|
||||
|
||||
import AVFoundation
|
||||
import MobileCoreServices
|
||||
import Social
|
||||
import UIKit
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
public let kSchemePrefix = "SharingMedia"
|
||||
public let kUserDefaultsKey = "SharingKey"
|
||||
public let kUserDefaultsMessageKey = "SharingMessageKey"
|
||||
public let kAppGroupIdKey = "AppGroupId"
|
||||
public let kAppChannel = "flutter_sharing_intent"
|
||||
|
||||
// extension UIViewController {
|
||||
// func showToast(_ message: String, duration: Double = 2.0) {
|
||||
// let toastLabel = UILabel()
|
||||
// toastLabel.backgroundColor = UIColor.black.withAlphaComponent(0.7)
|
||||
// toastLabel.textColor = UIColor.white
|
||||
// toastLabel.textAlignment = .center
|
||||
// toastLabel.font = UIFont.systemFont(ofSize: 14)
|
||||
// toastLabel.text = message
|
||||
// toastLabel.alpha = 0.0
|
||||
// toastLabel.numberOfLines = 0
|
||||
// toastLabel.layer.cornerRadius = 10
|
||||
// toastLabel.clipsToBounds = true
|
||||
//
|
||||
// let maxWidthPercentage: CGFloat = 0.8
|
||||
// let maxMessageSize = CGSize(
|
||||
// width: self.view.bounds.size.width * maxWidthPercentage,
|
||||
// height: self.view.bounds.size.height * maxWidthPercentage
|
||||
// )
|
||||
//
|
||||
// var expectedSize = toastLabel.sizeThatFits(maxMessageSize)
|
||||
// expectedSize.width += 24
|
||||
// expectedSize.height += 16
|
||||
//
|
||||
// toastLabel.frame = CGRect(
|
||||
// x: (self.view.frame.size.width - expectedSize.width) / 2,
|
||||
// y: self.view.frame.size.height - expectedSize.height - 50,
|
||||
// width: expectedSize.width,
|
||||
// height: expectedSize.height
|
||||
// )
|
||||
//
|
||||
// self.view.addSubview(toastLabel)
|
||||
//
|
||||
// UIView.animate(withDuration: 0.5, animations: {
|
||||
// toastLabel.alpha = 1.0
|
||||
// }) { _ in
|
||||
// UIView.animate(withDuration: 0.5, delay: duration, options: .curveEaseOut, animations: {
|
||||
// toastLabel.alpha = 0.0
|
||||
// }) { _ in
|
||||
// toastLabel.removeFromSuperview()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// @objc(FSIShareViewController)
|
||||
@available(swift, introduced: 5.0)
|
||||
open class FSIShareViewController: SLComposeServiceViewController {
|
||||
// MARK: - Config
|
||||
private(set) var hostAppBundleIdentifier: String = ""
|
||||
private(set) var appGroupId: String = ""
|
||||
|
||||
// Results
|
||||
private var sharedMedia: [SharingFile] = []
|
||||
|
||||
// Debug
|
||||
private let debugLogs = false
|
||||
|
||||
// MARK: - Lifecycle
|
||||
open override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
loadIds()
|
||||
}
|
||||
|
||||
open override func isContentValid() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
open override func didSelectPost() {
|
||||
if self.sharedMedia.isEmpty {
|
||||
if let text = self.contentText, !text.isEmpty {
|
||||
self.sharedMedia.append(
|
||||
SharingFile(value: text, thumbnail: nil, duration: nil, type: .text)
|
||||
)
|
||||
self.saveAndRedirect(message: text)
|
||||
return
|
||||
}
|
||||
self.completeAndExit()
|
||||
} else {
|
||||
self.saveAndRedirect()
|
||||
}
|
||||
// If the UI Post is used, save and redirect using contentText
|
||||
// saveAndRedirect(message: contentText)
|
||||
}
|
||||
|
||||
open override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
// Process attachments automatically on appear like original FSI
|
||||
processAttachments()
|
||||
}
|
||||
|
||||
// MARK: - Load Ids
|
||||
private func loadIds() {
|
||||
let shareExtId = Bundle.main.bundleIdentifier ?? ""
|
||||
if let idx = shareExtId.lastIndex(of: ".") {
|
||||
hostAppBundleIdentifier = String(shareExtId[..<idx])
|
||||
} else {
|
||||
hostAppBundleIdentifier = shareExtId
|
||||
}
|
||||
let custom = Bundle.main.object(forInfoDictionaryKey: kAppGroupIdKey) as? String
|
||||
appGroupId = custom ?? "group.\(hostAppBundleIdentifier)"
|
||||
log("loaded host=\(hostAppBundleIdentifier) group=\(appGroupId)")
|
||||
}
|
||||
|
||||
// MARK: - Attachment processing (clean RSI style, preserve FSI features)
|
||||
private func processAttachments() {
|
||||
guard let content = extensionContext?.inputItems.first as? NSExtensionItem else {
|
||||
completeAndExit()
|
||||
return
|
||||
}
|
||||
|
||||
guard let attachments = content.attachments, !attachments.isEmpty else {
|
||||
completeAndExit()
|
||||
return
|
||||
}
|
||||
|
||||
// Use DispatchGroup to wait for async loads
|
||||
let group = DispatchGroup()
|
||||
for (index, provider) in attachments.enumerated() {
|
||||
group.enter()
|
||||
// Try all SharedMediaType options similar to RSI but preserve explicit FSI order
|
||||
if provider.isImage {
|
||||
provider.loadItem(forTypeIdentifier: UType.image, options: nil) { [weak self] data, error in
|
||||
defer { group.leave() }
|
||||
guard let self = self, error == nil else { self?.dismissWithError(); return }
|
||||
self.handleImageItem(data: data, index: index, total: attachments.count)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if provider.isMovie {
|
||||
provider.loadItem(forTypeIdentifier: UType.movie, options: nil) { [weak self] data, error in
|
||||
defer { group.leave() }
|
||||
guard let self = self, error == nil else { self?.dismissWithError(); return }
|
||||
self.handleVideoItem(data: data, index: index, total: attachments.count)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if provider.isFile {
|
||||
provider.loadItem(forTypeIdentifier: UType.fileURL, options: nil) { [weak self] data, error in
|
||||
defer { group.leave() }
|
||||
guard let self = self, error == nil else { self?.dismissWithError(); return }
|
||||
self.handleFileItem(data: data, index: index, total: attachments.count)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if provider.isURL {
|
||||
provider.loadItem(forTypeIdentifier: UType.url, options: nil) { [weak self] data, error in
|
||||
defer { group.leave() }
|
||||
guard let self = self, error == nil else { self?.dismissWithError(); return }
|
||||
self.handleUrlItem(data: data, index: index, total: attachments.count)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if provider.isText {
|
||||
let id = provider.hasItemConformingToTypeIdentifier(UType.plainText)
|
||||
? UType.plainText
|
||||
: UType.text
|
||||
provider.loadItem(forTypeIdentifier: id, options: nil) { [weak self] data, error in
|
||||
defer { group.leave() }
|
||||
guard let self = self, error == nil else { self?.dismissWithError(); return }
|
||||
self.handleTextItem(data: data, index: index, total: attachments.count)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if provider.isData {
|
||||
provider.loadItem(forTypeIdentifier: UType.data, options: nil) { [weak self] data, error in
|
||||
defer { group.leave() }
|
||||
guard let self = self, error == nil else { self?.dismissWithError(); return }
|
||||
self.handleFileItem(data: data, index: index, total: attachments.count)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if provider.isItem {
|
||||
provider.loadItem(forTypeIdentifier: UType.item, options: nil) { [weak self] data, error in
|
||||
defer { group.leave() }
|
||||
guard let self = self, error == nil else { self?.dismissWithError(); return }
|
||||
self.handleFileItem(data: data, index: index, total: attachments.count)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
log("Unknown provider type: \(provider.registeredTypeIdentifiers)")
|
||||
|
||||
// Unknown type: just leave
|
||||
group.leave()
|
||||
}
|
||||
|
||||
group.notify(queue: .main) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
// if we have media -> media, else fallback to complete
|
||||
if !self.sharedMedia.isEmpty {
|
||||
self.saveAndRedirect()
|
||||
} else {
|
||||
print("FSIShare: No shared media → stopping.")
|
||||
self.completeAndExit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Individual handlers (preserve FSI behavior)
|
||||
private func handleTextItem(data: NSSecureCoding?, index: Int, total: Int) {
|
||||
if let s = data as? String {
|
||||
sharedMedia.append(SharingFile(value: s, thumbnail: nil, duration: nil, type: .text))
|
||||
} else if let url = data as? URL {
|
||||
sharedMedia.append(SharingFile(value: url.absoluteString, thumbnail: nil, duration: nil, type: .url))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func handleUrlItem(data: NSSecureCoding?, index: Int, total: Int) {
|
||||
if let url = data as? URL {
|
||||
sharedMedia.append(SharingFile(value: url.absoluteString, thumbnail: nil, duration: nil, type: .url))
|
||||
} else if let s = data as? String {
|
||||
sharedMedia.append(SharingFile(value: s, thumbnail: nil, duration: nil, type: .text))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func handleImageItem(data: NSSecureCoding?, index: Int, total: Int) {
|
||||
// data can be URL, UIImage, or Data
|
||||
if let url = data as? URL {
|
||||
let filename = getFileName(from: url, type: .image)
|
||||
if let dst = containerURL()?.appendingPathComponent(filename) {
|
||||
if copyFile(at: url, to: dst) {
|
||||
sharedMedia.append(SharingFile(value: dst.absoluteString, mimeType: url.mimeType(), thumbnail: nil, duration: nil, type: .image))
|
||||
}
|
||||
}
|
||||
} else if let img = data as? UIImage {
|
||||
if let saved = writeTempImage(img) {
|
||||
sharedMedia.append(saved)
|
||||
}
|
||||
} else if let raw = data as? Data, let img = UIImage(data: raw) {
|
||||
if let saved = writeTempImage(img) {
|
||||
sharedMedia.append(saved)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func handleVideoItem(data: NSSecureCoding?, index: Int, total: Int) {
|
||||
if let url = data as? URL {
|
||||
let filename = getFileName(from: url, type: .video)
|
||||
if let dst = containerURL()?.appendingPathComponent(filename) {
|
||||
if copyFile(at: url, to: dst) {
|
||||
if let m = getSharedMediaFile(forVideo: dst) {
|
||||
sharedMedia.append(m)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func handleFileItem(data: NSSecureCoding?, index: Int, total: Int) {
|
||||
if let url = data as? URL {
|
||||
let filename = getFileName(from: url, type: .file)
|
||||
if let dst = containerURL()?.appendingPathComponent(filename) {
|
||||
if copyFile(at: url, to: dst) {
|
||||
sharedMedia.append(SharingFile(value: dst.absoluteString, mimeType: url.mimeType(), thumbnail: nil, duration: nil, type: .file))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if let raw = data as? Data {
|
||||
let filename = "File_\(UUID().uuidString)"
|
||||
if let dst = containerURL()?.appendingPathComponent(filename) {
|
||||
do {
|
||||
try raw.write(to: dst)
|
||||
sharedMedia.append(SharingFile(value: dst.absoluteString, mimeType: "application/octet-stream", thumbnail: nil, duration: nil, type: .file))
|
||||
} catch {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Helpers: write temp image
|
||||
private func writeTempImage(_ image: UIImage) -> SharingFile? {
|
||||
guard let container = containerURL() else { return nil }
|
||||
let tempName = "TempImage_\(UUID().uuidString).png"
|
||||
let dst = container.appendingPathComponent(tempName)
|
||||
do {
|
||||
if let d = image.pngData() {
|
||||
try d.write(to: dst)
|
||||
let decoded = dst.absoluteString.removingPercentEncoding ?? dst.absoluteString
|
||||
return SharingFile(value: decoded, mimeType: "image/png", thumbnail: nil, duration: nil, type: .image)
|
||||
}
|
||||
} catch {
|
||||
log("writeTempImage error: \(error)")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
private func saveAndRedirect(message: String? = nil) {
|
||||
let ud = UserDefaults(suiteName: appGroupId)
|
||||
if !sharedMedia.isEmpty {
|
||||
if let data = try? JSONEncoder().encode(sharedMedia) {
|
||||
ud?.set(data, forKey: kUserDefaultsKey)
|
||||
}
|
||||
}
|
||||
ud?.set(message, forKey: kUserDefaultsMessageKey)
|
||||
ud?.synchronize()
|
||||
redirectToHostApp()
|
||||
}
|
||||
|
||||
|
||||
private func redirectToHostApp() {
|
||||
// kept for compatibility (RSI style)
|
||||
loadIds()
|
||||
// let raw = "\(kSchemePrefix)-\(hostAppBundleIdentifier):share"
|
||||
let raw = "\(kSchemePrefix)-\(hostAppBundleIdentifier)://dataUrl=\(kUserDefaultsKey)"
|
||||
guard let url = URL(string: raw.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? raw) else { completeAndExit(); return }
|
||||
|
||||
var responder: UIResponder? = self
|
||||
if #available(iOS 18.0, *) {
|
||||
while responder != nil {
|
||||
if let app = responder as? UIApplication { app.open(url, options: [:], completionHandler: nil) }
|
||||
responder = responder?.next
|
||||
}
|
||||
} else {
|
||||
let sel = sel_registerName("openURL:")
|
||||
while responder != nil {
|
||||
if responder?.responds(to: sel) ?? false { _ = responder?.perform(sel, with: url) }
|
||||
responder = responder?.next
|
||||
}
|
||||
}
|
||||
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
||||
}
|
||||
|
||||
// MARK: - File / thumbnail / metadata helpers
|
||||
func getExtension(from url: URL, type: SharingFileType) -> String {
|
||||
let parts = url.lastPathComponent.components(separatedBy: ".")
|
||||
var ex: String? = nil
|
||||
if parts.count > 1 { ex = parts.last }
|
||||
if ex == nil {
|
||||
switch type {
|
||||
case .image: ex = "png"
|
||||
case .video: ex = "mp4"
|
||||
case .file: ex = "txt"
|
||||
case .text: ex = "txt"
|
||||
case .url: ex = "txt"
|
||||
}
|
||||
}
|
||||
return ex ?? "bin"
|
||||
}
|
||||
|
||||
func getFileName(from url: URL, type: SharingFileType) -> String {
|
||||
var name = url.lastPathComponent
|
||||
if name.isEmpty { name = UUID().uuidString + "." + getExtension(from: url, type: type) }
|
||||
return name
|
||||
}
|
||||
|
||||
func copyFile(at srcURL: URL, to dstURL: URL) -> Bool {
|
||||
do {
|
||||
if FileManager.default.fileExists(atPath: dstURL.path) { try FileManager.default.removeItem(at: dstURL) }
|
||||
try FileManager.default.copyItem(at: srcURL, to: dstURL)
|
||||
return true
|
||||
} catch {
|
||||
log("copyFile error: \(error)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func getSharedMediaFile(forVideo: URL) -> SharingFile? {
|
||||
let asset = AVAsset(url: forVideo)
|
||||
let duration = (CMTimeGetSeconds(asset.duration) * 1000).rounded()
|
||||
let thumbnailPath = getThumbnailPath(for: forVideo)
|
||||
|
||||
if FileManager.default.fileExists(atPath: thumbnailPath.path) {
|
||||
return SharingFile(value: forVideo.absoluteString, mimeType: forVideo.mimeType(), thumbnail: thumbnailPath.absoluteString, duration: Int(duration), type: .video)
|
||||
}
|
||||
|
||||
let gen = AVAssetImageGenerator(asset: asset)
|
||||
gen.appliesPreferredTrackTransform = true
|
||||
gen.maximumSize = CGSize(width: 360, height: 360)
|
||||
|
||||
// Use first second or zero
|
||||
let time = CMTime(seconds: min(1.0, CMTimeGetSeconds(asset.duration)), preferredTimescale: 600)
|
||||
do {
|
||||
let cg = try gen.copyCGImage(at: time, actualTime: nil)
|
||||
if let data = UIImage(cgImage: cg).jpegData(compressionQuality: 0.8) {
|
||||
try data.write(to: thumbnailPath)
|
||||
return SharingFile(value: forVideo.absoluteString, mimeType: forVideo.mimeType(), thumbnail: thumbnailPath.absoluteString, duration: Int(duration), type: .video)
|
||||
}
|
||||
} catch {
|
||||
log("getSharedMediaFile thumbnail error: \(error)")
|
||||
}
|
||||
|
||||
// fallback
|
||||
return SharingFile(value: forVideo.absoluteString, mimeType: forVideo.mimeType(), thumbnail: nil, duration: Int(duration), type: .video)
|
||||
}
|
||||
|
||||
private func getThumbnailPath(for url: URL) -> URL {
|
||||
guard let container = containerURL() else { fatalError("App group not configured or missing") }
|
||||
let fileName = Data(url.lastPathComponent.utf8).base64EncodedString().replacingOccurrences(of: "=", with: "")
|
||||
return container.appendingPathComponent("\(fileName).jpg")
|
||||
}
|
||||
|
||||
private func containerURL() -> URL? {
|
||||
FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroupId)
|
||||
}
|
||||
|
||||
private func completeAndExit() {
|
||||
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
||||
}
|
||||
|
||||
private func dismissWithError() {
|
||||
log("[ERROR] Error loading data!")
|
||||
let alert = UIAlertController(title: "Error", message: "Error loading data", preferredStyle: .alert)
|
||||
alert.addAction(UIAlertAction(title: "OK", style: .cancel) { _ in self.dismiss(animated: true, completion: nil) })
|
||||
present(alert, animated: true, completion: nil)
|
||||
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
|
||||
}
|
||||
|
||||
private func writeTempFile(_ image: UIImage, to dstURL: URL) -> Bool {
|
||||
do {
|
||||
if FileManager.default.fileExists(atPath: dstURL.path) { try FileManager.default.removeItem(at: dstURL) }
|
||||
let pngData = image.pngData()
|
||||
try pngData?.write(to: dstURL)
|
||||
return true
|
||||
} catch (let error) {
|
||||
log("writeTempFile error: \(error)")
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
private func saveToUserDefaults(data: [SharingFile]) {
|
||||
let ud = UserDefaults(suiteName: appGroupId)
|
||||
if let enc = try? JSONEncoder().encode(data) { ud?.set(enc, forKey: kUserDefaultsKey); ud?.synchronize() }
|
||||
}
|
||||
|
||||
// MARK: - Logging
|
||||
private func log(_ s: String) { if debugLogs { print("[FSIShareVC] \(s)") } }
|
||||
|
||||
}
|
||||
|
||||
// MARK: - Extensions
|
||||
extension URL {
|
||||
func mimeType() -> String {
|
||||
if #available(iOS 14.0, *) {
|
||||
if let ut = UTType(filenameExtension: self.pathExtension), let m = ut.preferredMIMEType { return m }
|
||||
} else {
|
||||
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, self.pathExtension as NSString, nil)?.takeRetainedValue() {
|
||||
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() { return mimetype as String }
|
||||
}
|
||||
}
|
||||
return "application/octet-stream"
|
||||
}
|
||||
}
|
||||
|
||||
extension NSItemProvider {
|
||||
var isImage: Bool { return hasItemConformingToTypeIdentifier(UType.image) }
|
||||
var isMovie: Bool { return hasItemConformingToTypeIdentifier(UType.movie) }
|
||||
var isText: Bool {
|
||||
hasItemConformingToTypeIdentifier(UType.plainText) || hasItemConformingToTypeIdentifier(UType.text)
|
||||
}
|
||||
var isURL: Bool { return hasItemConformingToTypeIdentifier(UType.url) }
|
||||
var isFile: Bool { return hasItemConformingToTypeIdentifier(UType.fileURL) }
|
||||
var isData:Bool { return hasItemConformingToTypeIdentifier(UType.data) }
|
||||
var isItem: Bool { hasItemConformingToTypeIdentifier(UType.item) }
|
||||
|
||||
}
|
||||
|
||||
extension Array {
|
||||
subscript(safe index: UInt) -> Element? { return Int(index) < count ? self[Int(index)] : nil }
|
||||
}
|
||||
|
||||
|
||||
class SharingFile: Codable {
|
||||
var value: String
|
||||
var mimeType: String?
|
||||
var thumbnail: String?; // video thumbnail
|
||||
var duration: Int?; // video duration in milliseconds
|
||||
var type: SharingFileType;
|
||||
var message: String? // post message
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case value
|
||||
case mimeType
|
||||
case thumbnail
|
||||
case duration
|
||||
case type
|
||||
case message
|
||||
}
|
||||
|
||||
init(value: String, mimeType: String? = nil, thumbnail: String?, duration: Int?,
|
||||
type: SharingFileType, message: String?=nil) {
|
||||
self.value = value
|
||||
self.mimeType = mimeType
|
||||
self.thumbnail = thumbnail
|
||||
self.duration = duration
|
||||
self.type = type
|
||||
self.message = message
|
||||
}
|
||||
|
||||
// Debug method to print out SharedMediaFile details in the console
|
||||
func toString() {
|
||||
print("[SharingFile] \n\tvalue: \(self.value)\n\tthumbnail: \(self.thumbnail ?? "--" )\n\tduration: \(self.duration ?? 0)\n\ttype: \(self.type)\n\tmimeType: \(String(describing: self.mimeType))\n\tmessage: \(String(describing: self.message))")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum SharingFileType: Int, Codable {
|
||||
case text
|
||||
case url
|
||||
case image
|
||||
case video
|
||||
case file
|
||||
}
|
||||
|
||||
// Unified UTType → works on iOS 11–18
|
||||
enum UType {
|
||||
static var image: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.image.identifier
|
||||
} else {
|
||||
return kUTTypeImage as String // old API
|
||||
}
|
||||
}
|
||||
|
||||
static var movie: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.movie.identifier
|
||||
} else {
|
||||
return kUTTypeMovie as String
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static var url: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.url.identifier
|
||||
} else {
|
||||
return kUTTypeURL as String
|
||||
}
|
||||
}
|
||||
|
||||
static var fileURL: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.fileURL.identifier
|
||||
} else {
|
||||
return kUTTypeFileURL as String
|
||||
}
|
||||
}
|
||||
|
||||
static var text: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.text.identifier
|
||||
} else {
|
||||
return kUTTypeText as String
|
||||
}
|
||||
}
|
||||
|
||||
static var plainText: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.plainText.identifier
|
||||
} else {
|
||||
return kUTTypePlainText as String
|
||||
}
|
||||
}
|
||||
|
||||
static var data: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.data.identifier
|
||||
} else {
|
||||
return kUTTypeData as String
|
||||
}
|
||||
}
|
||||
|
||||
static var item: String {
|
||||
if #available(iOS 14.0, *) {
|
||||
return UTType.item.identifier
|
||||
} else {
|
||||
return kUTTypeItem as String
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
#import <Flutter/Flutter.h>
|
||||
|
||||
@interface FlutterSharingIntentPlugin : NSObject<FlutterPlugin>
|
||||
@end
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#import "FlutterSharingIntentPlugin.h"
|
||||
#if __has_include(<flutter_sharing_intent/flutter_sharing_intent-Swift.h>)
|
||||
#import <flutter_sharing_intent/flutter_sharing_intent-Swift.h>
|
||||
#else
|
||||
// Support project import fallback if the generated compatibility header
|
||||
// is not copied when this plugin is created as a library.
|
||||
// https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816
|
||||
#import "flutter_sharing_intent-Swift.h"
|
||||
#endif
|
||||
|
||||
@implementation FlutterSharingIntentPlugin
|
||||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||||
[SwiftFlutterSharingIntentPlugin registerWithRegistrar:registrar];
|
||||
}
|
||||
@end
|
||||
|
|
@ -0,0 +1,311 @@
|
|||
import Flutter
|
||||
import Photos
|
||||
import UIKit
|
||||
|
||||
public class SwiftFlutterSharingIntentPlugin: NSObject, FlutterStreamHandler, FlutterPlugin {
|
||||
static let kMessagesChannel = "\(kAppChannel)/messages"
|
||||
static let kEventsChannelMedia = "\(kAppChannel)/events-sharing";
|
||||
|
||||
private var initialSharing: [SharingFile]? = nil
|
||||
private var latestSharing: [SharingFile]? = nil
|
||||
|
||||
|
||||
private var eventSinkMedia: FlutterEventSink? = nil;
|
||||
// Singleton is required for calling functions directly from AppDelegate
|
||||
// - it is required if the developer is using also another library, which requires to call "application(_:open:options:)"
|
||||
// -> see Example app
|
||||
public static let instance = SwiftFlutterSharingIntentPlugin()
|
||||
|
||||
|
||||
public static func register(with registrar: FlutterPluginRegistrar) {
|
||||
let channel = FlutterMethodChannel(name: kAppChannel,binaryMessenger:registrar.messenger())
|
||||
|
||||
registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
|
||||
let chargingChannelMedia = FlutterEventChannel(name: kEventsChannelMedia, binaryMessenger: registrar.messenger())
|
||||
chargingChannelMedia.setStreamHandler(instance)
|
||||
|
||||
|
||||
registrar.addApplicationDelegate(instance)
|
||||
// registrar.addMethodCallDelegate(instance, channel: channel)
|
||||
}
|
||||
|
||||
// public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
// result("iOS " + UIDevice.current.systemVersion)
|
||||
// }
|
||||
|
||||
public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
|
||||
|
||||
switch call.method {
|
||||
case "getInitialSharing":
|
||||
result(toJson(data: self.initialSharing));
|
||||
/// Clear cache data to send only once
|
||||
self.initialSharing = nil
|
||||
self.latestSharing = nil
|
||||
|
||||
case "reset":
|
||||
self.initialSharing = nil
|
||||
self.latestSharing = nil
|
||||
result(nil);
|
||||
|
||||
case "getPlatformVersion" :
|
||||
result("iOS " + UIDevice.current.systemVersion);
|
||||
default:
|
||||
result(FlutterMethodNotImplemented);
|
||||
}
|
||||
}
|
||||
|
||||
// By Adding bundle id to prefix, we will ensure that the correct app will be openned
|
||||
public func hasSameSchemePrefix(url: URL?) -> Bool {
|
||||
if let url = url, let appDomain = Bundle.main.bundleIdentifier {
|
||||
return url.absoluteString.hasPrefix("\(kSchemePrefix)-\(appDomain)")
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// This is the function called on app startup with a shared link if the app had been closed already.
|
||||
// It is called as the launch process is finishing and the app is almost ready to run.
|
||||
// If the URL includes the module's ShareMedia prefix, then we process the URL and return true if we know how to handle that kind of URL or false if the app is not able to.
|
||||
// If the URL does not include the module's prefix, we must return true since while our module cannot handle the link, other modules might be and returning false can prevent
|
||||
// them from getting the chance to.
|
||||
// Reference: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application
|
||||
public func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [AnyHashable : Any] = [:]) -> Bool {
|
||||
if let url = launchOptions[UIApplication.LaunchOptionsKey.url] as? URL {
|
||||
if (hasSameSchemePrefix(url: url)) {
|
||||
return handleUrl(url: url, setInitialData: true)
|
||||
}
|
||||
return true
|
||||
} else if let activityDictionary = launchOptions[UIApplication.LaunchOptionsKey.userActivityDictionary] as? [AnyHashable: Any] {
|
||||
// Handle multiple URLs shared in
|
||||
for key in activityDictionary.keys {
|
||||
if let userActivity = activityDictionary[key] as? NSUserActivity {
|
||||
if let url = userActivity.webpageURL {
|
||||
if (hasSameSchemePrefix(url: url)) {
|
||||
return handleUrl(url: url, setInitialData: true)
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// This is the function called on resuming the app from a shared link.
|
||||
// It handles requests to open a resource by a specified URL. Returning true means that it was handled successfully, false means the attempt to open the resource failed.
|
||||
// If the URL includes the module's ShareMedia prefix, then we process the URL and return true if we know how to handle that kind of URL or false if we are not able to.
|
||||
// If the URL does not include the module's prefix, then we return false to indicate our module's attempt to open the resource failed and others should be allowed to.
|
||||
// Reference: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application
|
||||
public func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
|
||||
if (hasSameSchemePrefix(url: url)) {
|
||||
return handleUrl(url: url, setInitialData: false)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// This function is called by other modules like Firebase DeepLinks.
|
||||
// It tells the delegate that data for continuing an activity is available. Returning true means that our module handled the activity and that others do not have to. Returning false tells
|
||||
// iOS that our app did not handle the activity.
|
||||
// If the URL includes the module's ShareMedia prefix, then we process the URL and return true if we know how to handle that kind of URL or false if we are not able to.
|
||||
// If the URL does not include the module's prefix, then we must return false to indicate that this module did not handle the prefix and that other modules should try to.
|
||||
// Reference: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application
|
||||
public func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]) -> Void) -> Bool {
|
||||
if let url = userActivity.webpageURL {
|
||||
if (hasSameSchemePrefix(url: url)) {
|
||||
return handleUrl(url: url, setInitialData: true)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private func handleUrl(url: URL?, setInitialData: Bool) -> Bool {
|
||||
let appGroupId = Bundle.main.object(forInfoDictionaryKey: kAppGroupIdKey) as? String
|
||||
let defaultGroupId = "group.\(Bundle.main.bundleIdentifier!)"
|
||||
let userDefaults = UserDefaults(suiteName: appGroupId ?? defaultGroupId)
|
||||
|
||||
let message = userDefaults?.string(forKey: kUserDefaultsMessageKey)
|
||||
if let json = userDefaults?.object(forKey: kUserDefaultsKey) as? Data {
|
||||
let sharedArray = decode(data: json)
|
||||
let sharedMediaFiles: [SharingFile] = sharedArray.compactMap {
|
||||
guard let value = $0.type == .text || $0.type == .url ? $0.value
|
||||
: getAbsolutePath(for: $0.value) else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return SharingFile(
|
||||
value: value,
|
||||
mimeType: $0.mimeType,
|
||||
thumbnail: getAbsolutePath(for: $0.thumbnail),
|
||||
duration: $0.duration,
|
||||
type: $0.type,
|
||||
message: message
|
||||
)
|
||||
}
|
||||
latestSharing = sharedMediaFiles
|
||||
if(setInitialData) {
|
||||
initialSharing = latestSharing
|
||||
}
|
||||
eventSinkMedia?(toJson(data: latestSharing))
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// private func handleUrl(url: URL?, setInitialData: Bool) -> Bool {
|
||||
// if let url = url {
|
||||
// let appGroupId = (Bundle.main.object(forInfoDictionaryKey: kAppGroupIdKey) as? String) ?? "group.\(Bundle.main.bundleIdentifier!)"
|
||||
// let userDefaults = UserDefaults(suiteName: appGroupId)
|
||||
// let message = userDefaults?.string(forKey: kUserDefaultsMessageKey)
|
||||
// if let json = userDefaults?.object(forKey: kUserDefaultsKey) as? Data {
|
||||
// print("SwiftFlutterSharingIntentPlugin : [handleUrl] \(json)")
|
||||
// }
|
||||
// if url.fragment == "media" {
|
||||
// if let key = url.host?.components(separatedBy: "=").last,
|
||||
// let json = userDefaults?.object(forKey: key) as? Data {
|
||||
// let sharedArray = decode(data: json)
|
||||
//
|
||||
// let sharedMediaFiles: [SharingFile] = sharedArray.compactMap {
|
||||
// guard let value = getAbsolutePath(for: $0.value) else {
|
||||
// return nil
|
||||
// }
|
||||
// if ($0.type == .video && $0.thumbnail != nil) {
|
||||
// let thumbnail = getAbsolutePath(for: $0.thumbnail!)
|
||||
// return SharingFile.init(value: value, thumbnail: thumbnail, duration: $0.duration, type: $0.type)
|
||||
// } else if ($0.type == .video && $0.thumbnail == nil) {
|
||||
// return SharingFile.init(value: value, thumbnail: nil, duration: $0.duration, type: $0.type)
|
||||
// }
|
||||
//
|
||||
// return SharingFile.init(value: value, thumbnail: nil, duration: $0.duration, type: $0.type)
|
||||
// }
|
||||
// latestSharing = sharedMediaFiles
|
||||
// if(setInitialData) {
|
||||
// initialSharing = latestSharing
|
||||
// }
|
||||
// eventSinkMedia?(toJson(data: latestSharing))
|
||||
// }
|
||||
// } else if url.fragment == "file" {
|
||||
// if let key = url.host?.components(separatedBy: "=").last,
|
||||
// let json = userDefaults?.object(forKey: key) as? Data {
|
||||
// let sharedArray = decode(data: json)
|
||||
// let sharedMediaFiles: [SharingFile] = sharedArray.compactMap{
|
||||
// guard getAbsolutePath(for: $0.value) != nil else {
|
||||
// return nil
|
||||
// }
|
||||
// return SharingFile.init(value: $0.value,
|
||||
// thumbnail: nil, duration: nil,
|
||||
// type: $0.type)
|
||||
// }
|
||||
// latestSharing = sharedMediaFiles
|
||||
// if(setInitialData) {
|
||||
// initialSharing = latestSharing
|
||||
// }
|
||||
// eventSinkMedia?(toJson(data: latestSharing))
|
||||
// }
|
||||
// } else if url.fragment == "url" {
|
||||
// if let key = url.host?.components(separatedBy: "=").last,
|
||||
// let sharedArray = userDefaults?.object(forKey: key) as? [String] {
|
||||
// latestSharing = [SharingFile.init(value: sharedArray.joined(separator: ","), thumbnail: nil, duration: nil, type: SharingFileType.url)]
|
||||
// if(setInitialData) {
|
||||
// initialSharing = latestSharing
|
||||
// }
|
||||
// eventSinkMedia?(toJson(data: latestSharing))
|
||||
// }
|
||||
// } else if url.fragment == "text" {
|
||||
// if let key = url.host?.components(separatedBy: "=").last,
|
||||
// let sharedArray = userDefaults?.object(forKey: key) as? [String] {
|
||||
// latestSharing = [SharingFile.init(value: sharedArray.joined(separator: ","), thumbnail: nil, duration: nil, type: SharingFileType.text)]
|
||||
// if(setInitialData) {
|
||||
// initialSharing = latestSharing
|
||||
// }
|
||||
// eventSinkMedia?(toJson(data: latestSharing))
|
||||
// }
|
||||
// } else {
|
||||
// latestSharing = [SharingFile.init(value: url.absoluteString, thumbnail: nil, duration: nil, type: SharingFileType.text)]
|
||||
//
|
||||
// if(setInitialData) {
|
||||
// initialSharing = latestSharing
|
||||
// }
|
||||
// eventSinkMedia?(latestSharing)
|
||||
// }
|
||||
// return true
|
||||
// }
|
||||
// latestSharing = nil
|
||||
// return false
|
||||
// }
|
||||
|
||||
|
||||
public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
|
||||
if (arguments as! String? == "sharing" || arguments as! String? == "text" ) {
|
||||
eventSinkMedia = events;
|
||||
} else {
|
||||
return FlutterError.init(code: "NO_SUCH_ARGUMENT", message: "No such argument\(String(describing: arguments))", details: nil);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
public func onCancel(withArguments arguments: Any?) -> FlutterError? {
|
||||
if (arguments as! String? == "sharing" || arguments as! String? == "text" ) {
|
||||
eventSinkMedia = nil;
|
||||
} else {
|
||||
return FlutterError.init(code: "NO_SUCH_ARGUMENT", message: "No such argument as \(String(describing: arguments))", details: nil);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
private func getAbsolutePath(for identifier: String?) -> String? {
|
||||
guard let identifier else {
|
||||
return nil
|
||||
}
|
||||
|
||||
if (identifier.starts(with: "file://") || identifier.starts(with: "/var/mobile/Media") || identifier.starts(with: "/private/var/mobile")) {
|
||||
return identifier.replacingOccurrences(of: "file://", with: "")
|
||||
}
|
||||
guard let phAsset = PHAsset.fetchAssets(
|
||||
withLocalIdentifiers: [identifier],
|
||||
options: .none).firstObject else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let (url, _) = getFullSizeImageURLAndOrientation(for: phAsset)
|
||||
return url
|
||||
}
|
||||
|
||||
private func getFullSizeImageURLAndOrientation(for asset: PHAsset)-> (String?, Int) {
|
||||
var url: String? = nil
|
||||
var orientation: Int = 0
|
||||
let semaphore = DispatchSemaphore(value: 0)
|
||||
let options2 = PHContentEditingInputRequestOptions()
|
||||
options2.isNetworkAccessAllowed = true
|
||||
asset.requestContentEditingInput(with: options2){(input, info) in
|
||||
orientation = Int(input?.fullSizeImageOrientation ?? 0)
|
||||
url = input?.fullSizeImageURL?.path
|
||||
semaphore.signal()
|
||||
}
|
||||
semaphore.wait()
|
||||
return (url, orientation)
|
||||
}
|
||||
|
||||
private func decode(data: Data) -> [SharingFile] {
|
||||
do {
|
||||
let encodedData = try JSONDecoder().decode([SharingFile].self, from: data)
|
||||
return encodedData
|
||||
} catch {
|
||||
print("Decoding error:", error.localizedDescription)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
private func toJson(data: [SharingFile]?) -> String? {
|
||||
if data == nil {
|
||||
return nil
|
||||
}
|
||||
do {
|
||||
let encodedData = try JSONEncoder().encode(data)
|
||||
let json = String(data: encodedData, encoding: .utf8)!
|
||||
return json
|
||||
} catch {
|
||||
fatalError(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
8
flutter_sharing_intent/ios/Podfile
Normal file
8
flutter_sharing_intent/ios/Podfile
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
platform :ios, '12.0'
|
||||
|
||||
target 'Runner' do
|
||||
# ... existing pods
|
||||
|
||||
# Add the pod for the external library
|
||||
pod 'Evergage', '1.4.0'
|
||||
end
|
||||
52
flutter_sharing_intent/ios/Resources/PrivacyInfo.xcprivacy
Normal file
52
flutter_sharing_intent/ios/Resources/PrivacyInfo.xcprivacy
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<!--
|
||||
PrivacyInfo.xcprivacy
|
||||
Pods
|
||||
|
||||
Created by Bhagat on 18/05/24.
|
||||
Copyright (c) 2024 ___ORGANIZATIONNAME___. All rights reserved.
|
||||
-->
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSPrivacyTracking</key>
|
||||
<false/>
|
||||
|
||||
<key>NSPrivacyAccessedAPITypes</key>
|
||||
<array>
|
||||
<!-- <dict>-->
|
||||
<!-- <key>NSPrivacyAccessedAPIType</key>-->
|
||||
<!-- <string>NSPrivacyAccessedAPICategoryDiskSpace</string>-->
|
||||
<!-- <key>NSPrivacyAccessedAPITypeReasons</key>-->
|
||||
<!-- <array>-->
|
||||
<!-- <string>E174.1</string>-->
|
||||
<!-- </array>-->
|
||||
<!-- </dict>-->
|
||||
<dict>
|
||||
<key>NSPrivacyAccessedAPIType</key>
|
||||
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
|
||||
<key>NSPrivacyAccessedAPITypeReasons</key>
|
||||
<array>
|
||||
<string>1C8F.1</string>
|
||||
</array>
|
||||
</dict>
|
||||
<!-- <dict>-->
|
||||
<!-- <key>NSPrivacyAccessedAPIType</key>-->
|
||||
<!-- <string>NSPrivacyAccessedAPICategoryFileTimestamp</string>-->
|
||||
<!-- <key>NSPrivacyAccessedAPITypeReasons</key>-->
|
||||
<!-- <array>-->
|
||||
<!-- <string>C617.1</string>-->
|
||||
<!-- <string>0A2A.1</string>-->
|
||||
<!-- </array>-->
|
||||
<!-- </dict>-->
|
||||
<!-- <dict>-->
|
||||
<!-- <key>NSPrivacyAccessedAPIType</key>-->
|
||||
<!-- <string>NSPrivacyAccessedAPICategorySystemBootTime</string>-->
|
||||
<!-- <key>NSPrivacyAccessedAPITypeReasons</key>-->
|
||||
<!-- <array>-->
|
||||
<!-- <string>8FFB.1</string>-->
|
||||
<!-- </array>-->
|
||||
<!-- </dict>-->
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
35
flutter_sharing_intent/ios/flutter_sharing_intent.podspec
Normal file
35
flutter_sharing_intent/ios/flutter_sharing_intent.podspec
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
|
||||
# Run `pod lib lint flutter_sharing_intent.podspec` to validate before publishing.
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'flutter_sharing_intent'
|
||||
s.version = '1.0.1'
|
||||
s.summary = 'Sharing intent plugin for Flutter.'
|
||||
s.description = <<-DESC
|
||||
A Flutter plugin to receive sharing data in iOS and Android.
|
||||
DESC
|
||||
s.homepage = 'https://www.techind.co/'
|
||||
s.license = { :file => '../LICENSE' }
|
||||
s.author = { 'techind' => 'techind@gmail.com' }
|
||||
s.source = { :path => '.' }
|
||||
s.source_files = 'Classes/**/*'
|
||||
s.public_header_files = 'Classes/**/*.h'
|
||||
s.dependency 'Flutter'
|
||||
s.platform = :ios, '12.0'
|
||||
|
||||
# Flutter.framework does not contain a i386 slice.
|
||||
s.pod_target_xcconfig = {
|
||||
'DEFINES_MODULE' => 'YES',
|
||||
'BUILD_LIBRARY_FOR_DISTRIBUTION' => 'YES'
|
||||
# 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386'
|
||||
}
|
||||
|
||||
s.static_framework = true
|
||||
|
||||
# Add resource bundle for Apple manifest policy
|
||||
s.resource_bundle = {
|
||||
'MySDKPrivacy' => ['Resources/PrivacyInfo.xcprivacy']
|
||||
}
|
||||
s.swift_version = '5.0'
|
||||
end
|
||||
68
flutter_sharing_intent/lib/flutter_sharing_intent.dart
Normal file
68
flutter_sharing_intent/lib/flutter_sharing_intent.dart
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
||||
|
||||
import 'flutter_sharing_intent_platform_interface.dart';
|
||||
|
||||
class FlutterSharingIntent {
|
||||
static FlutterSharingIntent instance = FlutterSharingIntent._();
|
||||
factory FlutterSharingIntent() => instance;
|
||||
late EventChannel _eChannelMedia;
|
||||
Stream<List<SharedFile>>? _streamMedia;
|
||||
|
||||
FlutterSharingIntent._() {
|
||||
_eChannelMedia =
|
||||
const EventChannel("flutter_sharing_intent/events-sharing");
|
||||
}
|
||||
|
||||
Future<String?> getPlatformVersion() {
|
||||
return FlutterSharingIntentPlatform.instance.getPlatformVersion();
|
||||
}
|
||||
|
||||
/// Returns a [Future], which completes to one of the following:
|
||||
/// NOTE. The returned media on iOS (iOS ONLY) is already copied to a temp folder.
|
||||
/// So, you need to delete the file after you finish using it
|
||||
Future<List<SharedFile>> getInitialSharing() {
|
||||
return FlutterSharingIntentPlatform.instance.getInitialSharing();
|
||||
}
|
||||
|
||||
/// Call this method if you already consumed the callback
|
||||
/// and don't want the same callback again
|
||||
void reset() {
|
||||
return FlutterSharingIntentPlatform.instance.reset();
|
||||
}
|
||||
|
||||
/// Sets up a broadcast stream for receiving incoming media share change events.
|
||||
///
|
||||
/// Returns a broadcast [Stream] which emits events to listeners as follows:
|
||||
/// Errors occurring during stream activation or deactivation are reported
|
||||
/// through the `FlutterError` facility. Stream activation happens only when
|
||||
/// stream listener count changes from 0 to 1. Stream deactivation happens
|
||||
/// only when stream listener count changes from 1 to 0.
|
||||
///
|
||||
/// If the app was started by a link intent or user activity the stream will
|
||||
/// not emit that initial one - query either the `getInitialMedia` instead.
|
||||
Stream<List<SharedFile>> getMediaStream() {
|
||||
if (_streamMedia == null) {
|
||||
final stream =
|
||||
_eChannelMedia.receiveBroadcastStream("sharing").cast<String?>();
|
||||
_streamMedia = stream.transform<List<SharedFile>>(
|
||||
StreamTransformer<String?, List<SharedFile>>.fromHandlers(
|
||||
handleData: (String? data, EventSink<List<SharedFile>> sink) {
|
||||
if (data == null) {
|
||||
sink.add([]);
|
||||
} else {
|
||||
final encoded = jsonDecode(data);
|
||||
sink.add(encoded
|
||||
.map<SharedFile>((file) => SharedFile.fromJson(file))
|
||||
.toList());
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
return _streamMedia!;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
||||
|
||||
import 'flutter_sharing_intent_platform_interface.dart';
|
||||
|
||||
/// An implementation of [FlutterSharingIntentPlatform] that uses method channels.
|
||||
class MethodChannelFlutterSharingIntent extends FlutterSharingIntentPlatform {
|
||||
/// The method channel used to interact with the native platform.
|
||||
@visibleForTesting
|
||||
final methodChannel = const MethodChannel('flutter_sharing_intent');
|
||||
|
||||
@override
|
||||
Future<String?> getPlatformVersion() async {
|
||||
final version =
|
||||
await methodChannel.invokeMethod<String>('getPlatformVersion');
|
||||
return version;
|
||||
}
|
||||
|
||||
@override
|
||||
void reset() {
|
||||
methodChannel.invokeMethod('reset');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<SharedFile>> getInitialSharing() async {
|
||||
final json = await methodChannel.invokeMethod('getInitialSharing');
|
||||
if (json == null) return [];
|
||||
final encoded = jsonDecode(json);
|
||||
return encoded
|
||||
.map<SharedFile>((file) => SharedFile.fromJson(file))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
|
||||
import 'flutter_sharing_intent_method_channel.dart';
|
||||
|
||||
abstract class FlutterSharingIntentPlatform extends PlatformInterface {
|
||||
/// Constructs a FlutterSharingIntentPlatform.
|
||||
FlutterSharingIntentPlatform() : super(token: _token);
|
||||
|
||||
static final Object _token = Object();
|
||||
|
||||
static FlutterSharingIntentPlatform _instance =
|
||||
MethodChannelFlutterSharingIntent();
|
||||
|
||||
/// The default instance of [FlutterSharingIntentPlatform] to use.
|
||||
///
|
||||
/// Defaults to [MethodChannelFlutterSharingIntent].
|
||||
static FlutterSharingIntentPlatform get instance => _instance;
|
||||
|
||||
/// Platform-specific implementations should set this with their own
|
||||
/// platform-specific class that extends [FlutterSharingIntentPlatform] when
|
||||
/// they register themselves.
|
||||
static set instance(FlutterSharingIntentPlatform instance) {
|
||||
PlatformInterface.verifyToken(instance, _token);
|
||||
_instance = instance;
|
||||
}
|
||||
|
||||
Future<String?> getPlatformVersion() {
|
||||
throw UnimplementedError('platformVersion() has not been implemented.');
|
||||
}
|
||||
|
||||
Future<List<SharedFile>> getInitialSharing() async {
|
||||
throw UnimplementedError('getInitialSharing() has not been implemented.');
|
||||
}
|
||||
|
||||
void reset() async {
|
||||
throw UnimplementedError('reset() has not been implemented.');
|
||||
}
|
||||
}
|
||||
59
flutter_sharing_intent/lib/model/sharing_file.dart
Normal file
59
flutter_sharing_intent/lib/model/sharing_file.dart
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// ignore_for_file: constant_identifier_names
|
||||
|
||||
class SharedFile {
|
||||
/// Image or Video path or text
|
||||
/// NOTE. for iOS only the file is always copied
|
||||
String? value;
|
||||
|
||||
/// Video thumbnail
|
||||
String? thumbnail;
|
||||
|
||||
/// Video duration in milliseconds
|
||||
int? duration;
|
||||
|
||||
/// Whether its a video or image or file
|
||||
SharedMediaType type = SharedMediaType.OTHER;
|
||||
|
||||
/// Mime type of the file.
|
||||
/// i.e. image/jpeg, video/mp4, text/plain
|
||||
final String? mimeType;
|
||||
|
||||
/// Post message iOS ONLY
|
||||
final String? message;
|
||||
|
||||
SharedFile(
|
||||
{required this.value,
|
||||
this.thumbnail,
|
||||
this.duration,
|
||||
this.type = SharedMediaType.OTHER,
|
||||
this.mimeType,
|
||||
this.message});
|
||||
|
||||
SharedFile.fromJson(Map<String, dynamic> json)
|
||||
: value = json['value'] ?? json['path'],
|
||||
thumbnail = json['thumbnail'],
|
||||
duration = json['duration'],
|
||||
type = json['type'] is int
|
||||
? SharedMediaType.values[json['type']]
|
||||
: SharedMediaType.OTHER,
|
||||
mimeType = json['mimeType'],
|
||||
message = json['message'];
|
||||
|
||||
Map<String, dynamic> toMap() {
|
||||
return {
|
||||
'value': value,
|
||||
'thumbnail': thumbnail,
|
||||
'duration': duration,
|
||||
'type': type.index,
|
||||
'mimeType': mimeType,
|
||||
'message': message,
|
||||
};
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return "{ value:$value, thumbnail:$thumbnail, duration:$duration, type:$type, mimeType:$mimeType, message:$message }";
|
||||
}
|
||||
}
|
||||
|
||||
enum SharedMediaType { TEXT, URL, IMAGE, VIDEO, FILE, WEB_SEARCH, OTHER }
|
||||
43
flutter_sharing_intent/pubspec.yaml
Normal file
43
flutter_sharing_intent/pubspec.yaml
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
name: flutter_sharing_intent
|
||||
description: A flutter plugin that allow flutter apps to receive photos, videos, text, urls or any other file types from another app.
|
||||
version: 2.0.4
|
||||
homepage: https://github.com/bhagat-techind/flutter_sharing_intent
|
||||
|
||||
environment:
|
||||
# sdk: '>=3.0.5 <4.0.0'
|
||||
sdk: ">=3.1.2 <4.0.0"
|
||||
flutter: ">=3.3.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
plugin_platform_interface: ^2.1.8
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
flutter_lints: ^6.0.0
|
||||
|
||||
# For information on the generic Dart part of this file, see the
|
||||
# following page: https://dart.dev/tools/pub/pubspec
|
||||
|
||||
# The following section is specific to Flutter packages.
|
||||
flutter:
|
||||
# This section identifies this Flutter project as a plugin project.
|
||||
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
|
||||
# which should be registered in the plugin registry. This is required for
|
||||
# using method channels.
|
||||
# The Android 'package' specifies package in which the registered class is.
|
||||
# This is required for using method channels on Android.
|
||||
# The 'ffiPlugin' specifies that native code should be built and bundled.
|
||||
# This is required for using `dart:ffi`.
|
||||
# All these are used by the tooling to maintain consistency when
|
||||
# adding or updating assets for this project.
|
||||
plugin:
|
||||
platforms:
|
||||
android:
|
||||
package: com.techind.flutter_sharing_intent
|
||||
pluginClass: FlutterSharingIntentPlugin
|
||||
ios:
|
||||
pluginClass: FlutterSharingIntentPlugin
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_sharing_intent/flutter_sharing_intent_method_channel.dart';
|
||||
|
||||
void main() {
|
||||
MethodChannelFlutterSharingIntent platform =
|
||||
MethodChannelFlutterSharingIntent();
|
||||
const MethodChannel channel = MethodChannel('flutter_sharing_intent');
|
||||
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
setUp(() {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, (MethodCall methodCall) async {
|
||||
return '42';
|
||||
});
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
|
||||
.setMockMethodCallHandler(channel, null);
|
||||
});
|
||||
|
||||
test('getPlatformVersion', () async {
|
||||
expect(await platform.getPlatformVersion(), '42');
|
||||
});
|
||||
}
|
||||
45
flutter_sharing_intent/test/flutter_sharing_intent_test.dart
Normal file
45
flutter_sharing_intent/test/flutter_sharing_intent_test.dart
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:flutter_sharing_intent/flutter_sharing_intent.dart';
|
||||
import 'package:flutter_sharing_intent/flutter_sharing_intent_platform_interface.dart';
|
||||
import 'package:flutter_sharing_intent/flutter_sharing_intent_method_channel.dart';
|
||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||
|
||||
class MockFlutterSharingIntentPlatform
|
||||
with MockPlatformInterfaceMixin
|
||||
implements FlutterSharingIntentPlatform {
|
||||
@override
|
||||
Future<String?> getPlatformVersion() => Future.value('42');
|
||||
|
||||
@override
|
||||
Future<List<SharedFile>> getInitialSharing() {
|
||||
return Future.value(
|
||||
[SharedFile(value: "Test", type: SharedMediaType.TEXT)]);
|
||||
}
|
||||
|
||||
@override
|
||||
void reset() {}
|
||||
}
|
||||
|
||||
void main() {
|
||||
final FlutterSharingIntentPlatform initialPlatform =
|
||||
FlutterSharingIntentPlatform.instance;
|
||||
|
||||
test('$MethodChannelFlutterSharingIntent is the default instance', () {
|
||||
expect(initialPlatform, isInstanceOf<MethodChannelFlutterSharingIntent>());
|
||||
});
|
||||
|
||||
FlutterSharingIntent flutterSharingIntentPlugin = FlutterSharingIntent();
|
||||
MockFlutterSharingIntentPlatform fakePlatform =
|
||||
MockFlutterSharingIntentPlatform();
|
||||
FlutterSharingIntentPlatform.instance = fakePlatform;
|
||||
|
||||
test('getPlatformVersion', () async {
|
||||
expect(await flutterSharingIntentPlugin.getPlatformVersion(), '42');
|
||||
});
|
||||
|
||||
test('getInitialSharing', () async {
|
||||
var sharingData = await flutterSharingIntentPlugin.getInitialSharing();
|
||||
expect(sharingData.first.value, 'Test');
|
||||
});
|
||||
}
|
||||
|
|
@ -1,413 +0,0 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "5b7468c326d2f8a4f630056404ca0d291ade42918f4a3c6233618e724f39da8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "92.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "70e4b1ef8003c64793a9e268a551a82869a8a96f39deb73dea28084b0e8bf75e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
base32:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: base32
|
||||
sha256: "37548444aaee8bd5e91db442ce69ee3a79d3652ed47c1fa7568aa3bb9af0aea5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
base_codecs:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: base_codecs
|
||||
sha256: "41701a12ede9912663decd708279924ece5018566daa7d1f484d5f4f10894f91"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
benchmark_harness:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: benchmark_harness
|
||||
sha256: a2d3c4c83cac0126bf38e41eaf7bd9ed4f6635f1ee1a0cbc6f79fa9736c62cbd
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
cli_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_config
|
||||
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: lints
|
||||
sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.18"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.2"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.13"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
sha256: "77cc98ea27006c84e71a7356cf3daf9ddbde2d91d84f77dbfe64cf0e4d9611ae"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.28.0"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.8"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: f1072617a6657e5fc09662e721307f7fb009b4ed89b19f47175d11d5254a62d4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.14"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.0.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: "592ab6e2892f67760543fb712ff0177f4ec76c031f02f5b4ff8d3fc5eb9fb61a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.4"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket
|
||||
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.10.0 <4.0.0"
|
||||
|
|
@ -1,357 +0,0 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "5b7468c326d2f8a4f630056404ca0d291ade42918f4a3c6233618e724f39da8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "92.0.0"
|
||||
analyzer:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "70e4b1ef8003c64793a9e268a551a82869a8a96f39deb73dea28084b0e8bf75e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "9.0.0"
|
||||
archive:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: archive
|
||||
sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.7"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
dart_style:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: dart_style
|
||||
sha256: a9c30492da18ff84efe2422ba2d319a89942d93e58eb0b73d32abe822ef54b7b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: flutter_lints
|
||||
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
lints:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: lints
|
||||
sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
path:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
posix:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: posix
|
||||
sha256: "6323a5b0fa688b6a010df4905a56b00181479e6d10534cecfecede2aa55add61"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.3"
|
||||
pub_semver:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
vector_math:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.0.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: f52385d4f73589977c80797e60fe51014f7f2b957b5e9a62c3f6ada439889249
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
yaml:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: yaml
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.9.0 <4.0.0"
|
||||
flutter: ">=3.35.0"
|
||||
|
|
@ -1,493 +0,0 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "67.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.4.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
cli_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_config
|
||||
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.15.6"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.9.0"
|
||||
lints:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: lints
|
||||
sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
markdown:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: markdown
|
||||
sha256: "935e23e1ff3bc02d390bad4d4be001208ee92cc217cb5b5a6c19bc14aaa318c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.3.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
pana:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: pana
|
||||
sha256: "6f4372d5d2af5fe3fc6491c18f575601743bceb8433c7f179a6fffd162ee55f1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.21.39"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.0"
|
||||
retry:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: retry
|
||||
sha256: "822e118d5b3aafed083109c72d5f484c6dc66707885e07c0fbcb8b986bba7efc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
safe_url_check:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: safe_url_check
|
||||
sha256: "49a3e060a7869cbafc8f4845ca1ecbbaaa53179980a32f4fdfeab1607e90f41d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.2"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.13"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
tar:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: tar
|
||||
sha256: "22f67e2d77b51050436620b2a5de521c58ca6f0b75af1d9ab3c8cae2eae58fcd"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.26.3"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.12"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.0.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: f52385d4f73589977c80797e60fe51014f7f2b957b5e9a62c3f6ada439889249
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket
|
||||
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.8.0 <4.0.0"
|
||||
|
|
@ -1,469 +0,0 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
_fe_analyzer_shared:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _fe_analyzer_shared
|
||||
sha256: c209688d9f5a5f26b2fb47a188131a6fb9e876ae9e47af3737c0b4f58a93470d
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "91.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
sha256: f51c8499b35f9b26820cfe914828a6a98a94efd5cc78b37bb7d03debae3a1d08
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.4.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
cli_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_config
|
||||
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
coverage:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: coverage
|
||||
sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.15.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
frontend_server_client:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: frontend_server_client
|
||||
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
sha256: aa6199f908078bb1c5efb8d8638d4ae191aac11b311132c3ef48ce352fb52ef8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
sha256: dfd5a80599cf0165756e3181807ed3e77daf6dd4137caaad72d0b7931597650b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
sha256: "53385261521cc4a0c4658fd0ad07a7d14591cf8fc33abbceae306ddb974888dc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.2"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
node_preamble:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_preamble
|
||||
sha256: "6e7eac89047ab8a8d26cf16127b5ed26de65209847630400f9aefd7cd5c730db"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.2"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.5.2"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.2"
|
||||
shelf_packages_handler:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_packages_handler
|
||||
sha256: "89f967eca29607c933ba9571d838be31d67f53f6e4ee15147d5dc2934fee1b1e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
shelf_static:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_static
|
||||
sha256: c87c3875f91262785dade62d135760c2c69cb217ac759485334c5857ad89f6e3
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
sha256: "3632775c8e90d6c9712f883e633716432a27758216dfb61bd86a8321c0580925"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
source_map_stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_map_stack_trace
|
||||
sha256: c0713a43e323c3302c2abe2a1cc89aa057a387101ebd280371d6a6c9fa68516b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
source_maps:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_maps
|
||||
sha256: "190222579a448b03896e0ca6eca5998fa810fda630c1d65e2f78b3f638f54812"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.13"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: test
|
||||
sha256: "75906bf273541b676716d1ca7627a17e4c4070a3a16272b7a3dc7da3b9f3f6b7"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.26.3"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
test_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_core
|
||||
sha256: "0cc24b5ff94b38d2ae73e1eb43cc302b77964fbf67abad1e296025b78deb53d0"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.12"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.0.2"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
sha256: f52385d4f73589977c80797e60fe51014f7f2b957b5e9a62c3f6ada439889249
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket
|
||||
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.3"
|
||||
webkit_inspection_protocol:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: webkit_inspection_protocol
|
||||
sha256: "87d3f2333bb240704cd3f1c6b5b7acd8a10e7f0bc28c28dcf14e782014f4a572"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.1"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.9.0 <4.0.0"
|
||||
flutter: ">=3.18.0-18.0.pre.54"
|
||||
|
|
@ -5,6 +5,8 @@ dependency_overrides:
|
|||
path: ./dependencies/dots_indicator
|
||||
ed25519_edwards:
|
||||
path: ./dependencies/ed25519_edwards
|
||||
flutter_sharing_intent:
|
||||
path: ./dependencies/flutter_sharing_intent
|
||||
hand_signature:
|
||||
path: ./dependencies/hand_signature
|
||||
hashlib:
|
||||
|
|
|
|||
|
|
@ -1,197 +0,0 @@
|
|||
# Generated by pub
|
||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||
packages:
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
qr:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: qr
|
||||
sha256: "5a1d2586170e172b8a8c8470bbbffd5eb0cd38a66c0d77155ea138d3af3a4445"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.7"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.0.2"
|
||||
sdks:
|
||||
dart: ">=3.8.0-0 <4.0.0"
|
||||
flutter: ">=3.18.0-18.0.pre.54"
|
||||
|
|
@ -42,7 +42,7 @@ def integrate_package(folder_name, data):
|
|||
global config_lock
|
||||
|
||||
repo_url = data['git']
|
||||
keep_list = ["lib", "test", "LICENSE", "pubspec.yaml"]
|
||||
keep_list = ["lib", "test", "LICENSE", "pubspec.yaml", "android", "ios"]
|
||||
if "keep" in data:
|
||||
keep_list += [item.rstrip('/') for item in data['keep']]
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue