TF-3250 Fix Share file from external to Twake Mail sometimes open home screen only
This commit is contained in:
@@ -79,12 +79,6 @@
|
||||
<data android:scheme="mailto"/>
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="text/*" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
@@ -7,4 +7,6 @@ class Constant {
|
||||
static const octetStreamMimeType = 'application/octet-stream';
|
||||
static const pdfExtension = '.pdf';
|
||||
static const imageType = 'image';
|
||||
static const textVCardMimeType = 'text/x-vcard';
|
||||
static const textPlainMimeType = 'text/plain';
|
||||
}
|
||||
@@ -32,6 +32,10 @@ target 'Runner' do
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
|
||||
target 'TeamMailShareExtension' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
|
||||
+3
-3
@@ -183,7 +183,7 @@ PODS:
|
||||
- Flutter
|
||||
- PromisesObjC (2.3.1)
|
||||
- ReachabilitySwift (5.0.0)
|
||||
- receive_sharing_intent (0.0.1):
|
||||
- receive_sharing_intent (1.8.1):
|
||||
- Flutter
|
||||
- SDWebImage (5.18.10):
|
||||
- SDWebImage/Core (= 5.18.10)
|
||||
@@ -380,7 +380,7 @@ SPEC CHECKSUMS:
|
||||
printing: 233e1b73bd1f4a05615548e9b5a324c98588640b
|
||||
PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4
|
||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||
receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
|
||||
receive_sharing_intent: 79c848f5b045674ad60b9fea3bafea59962ad2c1
|
||||
SDWebImage: fc8f2d48bbfd72ef39d70e981bd24a3f3be53fec
|
||||
SDWebImageWebPCoder: 633b813fca24f1de5e076bcd7f720c038b23892b
|
||||
share_plus: c3fef564749587fc939ef86ffb283ceac0baf9f5
|
||||
@@ -390,6 +390,6 @@ SPEC CHECKSUMS:
|
||||
url_launcher_ios: 68d46cc9766d0c41dbdc884310529557e3cd7a86
|
||||
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
|
||||
|
||||
PODFILE CHECKSUM: ded4724b53568389542fa0f7d7a64c05ffc03971
|
||||
PODFILE CHECKSUM: f2eb8f5a17c320a935d112236893d073c572e17e
|
||||
|
||||
COCOAPODS: 1.14.3
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
756BBC4C51FCB44047AB39E4 /* Pods_TeamMailShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 143BD7B2CF181BA69CDE351A /* Pods_TeamMailShareExtension.framework */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
@@ -48,7 +49,6 @@
|
||||
F5BBBF512B2EEC37007930E1 /* NetworkExceptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BBBF502B2EEC37007930E1 /* NetworkExceptions.swift */; };
|
||||
F5BBBF532B2EECAA007930E1 /* JmapExceptions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BBBF522B2EECAA007930E1 /* JmapExceptions.swift */; };
|
||||
F5BBBF552B2EEF3D007930E1 /* BundleExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5BBBF542B2EEF3D007930E1 /* BundleExtension.swift */; };
|
||||
F5CFE0302B335098005A90A9 /* TwakeLogger.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5EFC07C2B328B9F00829056 /* TwakeLogger.swift */; };
|
||||
F5CFE0352B335322005A90A9 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
|
||||
F5D4EA032B2ABF090090DDFC /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = F5D4EA022B2ABF090090DDFC /* NotificationService.swift */; };
|
||||
F5D4EA072B2ABF090090DDFC /* TwakeMailNSE.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = F5D4EA002B2ABF090090DDFC /* TwakeMailNSE.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
@@ -118,8 +118,11 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
06C73A54FA0478D3C89AB5E5 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
07753111B751BFDB3187FE6F /* Pods-TeamMailShareExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TeamMailShareExtension.debug.xcconfig"; path = "Target Support Files/Pods-TeamMailShareExtension/Pods-TeamMailShareExtension.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
143BD7B2CF181BA69CDE351A /* Pods_TeamMailShareExtension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TeamMailShareExtension.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
1FB76FA91BBCB2BF7B08705B /* Pods-TeamMailShareExtension.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TeamMailShareExtension.profile.xcconfig"; path = "Target Support Files/Pods-TeamMailShareExtension/Pods-TeamMailShareExtension.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
4D124E74293A67D900BA5186 /* RunnerProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerProfile.entitlements; sourceTree = "<group>"; };
|
||||
5810EDDA99BEFEACD742F507 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -135,6 +138,7 @@
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
B2EAFF659572E6B9F5AFAAF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
BC08294F5AE09BF8CC592AD1 /* Pods-TeamMailShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TeamMailShareExtension.release.xcconfig"; path = "Target Support Files/Pods-TeamMailShareExtension/Pods-TeamMailShareExtension.release.xcconfig"; sourceTree = "<group>"; };
|
||||
F522E87E2C0EE23400DDA35B /* AuthenticationSSOTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationSSOTests.swift; sourceTree = "<group>"; };
|
||||
F522E8852C0EE8B600DDA35B /* CoreUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreUtils.swift; sourceTree = "<group>"; };
|
||||
F52F992D27FD6EB900346091 /* TeamMailShareExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = TeamMailShareExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -197,6 +201,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
756BBC4C51FCB44047AB39E4 /* Pods_TeamMailShareExtension.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -223,6 +228,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
5810EDDA99BEFEACD742F507 /* Pods_Runner.framework */,
|
||||
143BD7B2CF181BA69CDE351A /* Pods_TeamMailShareExtension.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -482,6 +488,9 @@
|
||||
B2EAFF659572E6B9F5AFAAF8 /* Pods-Runner.debug.xcconfig */,
|
||||
631346BB444C71671599207F /* Pods-Runner.release.xcconfig */,
|
||||
06C73A54FA0478D3C89AB5E5 /* Pods-Runner.profile.xcconfig */,
|
||||
07753111B751BFDB3187FE6F /* Pods-TeamMailShareExtension.debug.xcconfig */,
|
||||
BC08294F5AE09BF8CC592AD1 /* Pods-TeamMailShareExtension.release.xcconfig */,
|
||||
1FB76FA91BBCB2BF7B08705B /* Pods-TeamMailShareExtension.profile.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
@@ -510,8 +519,6 @@
|
||||
F5D4EA062B2ABF090090DDFC /* PBXTargetDependency */,
|
||||
);
|
||||
name = Runner;
|
||||
packageProductDependencies = (
|
||||
);
|
||||
productName = Runner;
|
||||
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
@@ -520,6 +527,7 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = F52F993827FD6EB900346091 /* Build configuration list for PBXNativeTarget "TeamMailShareExtension" */;
|
||||
buildPhases = (
|
||||
E791D44F3C4EDE784D610B9E /* [CP] Check Pods Manifest.lock */,
|
||||
F52F992927FD6EB900346091 /* Sources */,
|
||||
F52F992A27FD6EB900346091 /* Frameworks */,
|
||||
F52F992B27FD6EB900346091 /* Resources */,
|
||||
@@ -696,7 +704,7 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
|
||||
};
|
||||
3D8E7FEF3D91E77326493F6D /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
@@ -735,6 +743,28 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
|
||||
};
|
||||
E791D44F3C4EDE784D610B9E /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-TeamMailShareExtension-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@@ -759,7 +789,6 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
F5CFE0302B335098005A90A9 /* TwakeLogger.swift in Sources */,
|
||||
F52F993027FD6EB900346091 /* ShareViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
@@ -1120,7 +1149,9 @@
|
||||
};
|
||||
F52F993927FD6EB900346091 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 07753111B751BFDB3187FE6F /* Pods-TeamMailShareExtension.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
APP_GROUP_ID = group.com.linagora.teammail;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
@@ -1160,7 +1191,9 @@
|
||||
};
|
||||
F52F993A27FD6EB900346091 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = BC08294F5AE09BF8CC592AD1 /* Pods-TeamMailShareExtension.release.xcconfig */;
|
||||
buildSettings = {
|
||||
APP_GROUP_ID = group.com.linagora.teammail;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
@@ -1197,7 +1230,9 @@
|
||||
};
|
||||
F52F993B27FD6EB900346091 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1FB76FA91BBCB2BF7B08705B /* Pods-TeamMailShareExtension.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
APP_GROUP_ID = group.com.linagora.teammail;
|
||||
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1510"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "F52F992C27FD6EB900346091"
|
||||
BuildableName = "TeamMailShareExtension.appex"
|
||||
BlueprintName = "TeamMailShareExtension"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
shouldAutocreateTestPlan = "YES">
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
askForAppToLaunch = "Yes"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
askForAppToLaunch = "Yes"
|
||||
launchAutomaticallySubstyle = "2">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
|
||||
BuildableName = "Runner.app"
|
||||
BlueprintName = "Runner"
|
||||
ReferencedContainer = "container:Runner.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -2,6 +2,8 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>AppGroupId</key>
|
||||
<string>${APP_GROUP_ID}</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
|
||||
@@ -1,354 +1,4 @@
|
||||
import UIKit
|
||||
import Social
|
||||
import MobileCoreServices
|
||||
import Photos
|
||||
import receive_sharing_intent
|
||||
|
||||
class ShareViewController: SLComposeServiceViewController {
|
||||
var hostAppBundleIdentifier = ""
|
||||
let appGroupId = "group.com.linagora.teammail"
|
||||
let sharedKey = "ShareKey"
|
||||
var sharedMedia: [SharedMediaFile] = []
|
||||
var sharedText: [String] = []
|
||||
let imageContentType = kUTTypeImage as String
|
||||
let textContentType = kUTTypeText as String
|
||||
let urlContentType = kUTTypeURL as String
|
||||
let videoContentType = kUTTypeMovie as String
|
||||
let fileURLType = kUTTypeFileURL as String
|
||||
|
||||
override func isContentValid() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
private func loadIds() {
|
||||
// loading Share extension App Id
|
||||
let shareExtensionAppBundleIdentifier = Bundle.main.bundleIdentifier!;
|
||||
|
||||
|
||||
// convert ShareExtension id to host app id
|
||||
// By default it is remove last part of id after last point
|
||||
// For example: com.test.ShareExtension -> com.test
|
||||
let lastIndexOfPoint = shareExtensionAppBundleIdentifier.lastIndex(of: ".");
|
||||
hostAppBundleIdentifier = String(shareExtensionAppBundleIdentifier[..<lastIndexOfPoint!]);
|
||||
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad();
|
||||
|
||||
// load group and app id from build info
|
||||
loadIds();
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
|
||||
if let content = extensionContext!.inputItems[0] as? NSExtensionItem {
|
||||
if let contents = content.attachments {
|
||||
for (index, attachment) in (contents).enumerated() {
|
||||
if attachment.hasItemConformingToTypeIdentifier(imageContentType) {
|
||||
handleImages(content: content, attachment: attachment, index: index)
|
||||
} else if attachment.hasItemConformingToTypeIdentifier(textContentType) {
|
||||
handleText(content: content, attachment: attachment, index: index)
|
||||
} else if attachment.hasItemConformingToTypeIdentifier(urlContentType) {
|
||||
handleUrl(content: content, attachment: attachment, index: index)
|
||||
} else if attachment.hasItemConformingToTypeIdentifier(fileURLType) {
|
||||
handleFiles(content: content, attachment: attachment, index: index)
|
||||
} else if attachment.hasItemConformingToTypeIdentifier(videoContentType) {
|
||||
handleVideos(content: content, attachment: attachment, index: index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func didSelectPost() {
|
||||
TwakeLogger.shared.log(message: "didSelectPost");
|
||||
}
|
||||
|
||||
override func configurationItems() -> [Any]! {
|
||||
// To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here.
|
||||
return []
|
||||
}
|
||||
|
||||
private func handleText (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
||||
attachment.loadItem(forTypeIdentifier: textContentType, options: nil) { [weak self] data, error in
|
||||
|
||||
if error == nil, let item = data as? String, let this = self {
|
||||
|
||||
this.sharedText.append(item)
|
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app
|
||||
if index == (content.attachments?.count)! - 1 {
|
||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
||||
userDefaults?.set(this.sharedText, forKey: this.sharedKey)
|
||||
userDefaults?.synchronize()
|
||||
this.redirectToHostApp(type: .text)
|
||||
}
|
||||
|
||||
} else {
|
||||
self?.dismissWithError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleUrl (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
||||
attachment.loadItem(forTypeIdentifier: urlContentType, options: nil) { [weak self] data, error in
|
||||
|
||||
if error == nil, let item = data as? URL, let this = self {
|
||||
|
||||
this.sharedText.append(item.absoluteString)
|
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app
|
||||
if index == (content.attachments?.count)! - 1 {
|
||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
||||
userDefaults?.set(this.sharedText, forKey: this.sharedKey)
|
||||
userDefaults?.synchronize()
|
||||
this.redirectToHostApp(type: .text)
|
||||
}
|
||||
|
||||
} else {
|
||||
self?.dismissWithError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleImages (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
||||
attachment.loadItem(forTypeIdentifier: imageContentType, options: nil) { [weak self] data, error in
|
||||
|
||||
if error == nil, let url = data as? URL, let this = self {
|
||||
|
||||
// Always copy
|
||||
let fileName = this.getFileName(from: url, type: .image)
|
||||
let newPath = FileManager.default
|
||||
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
|
||||
.appendingPathComponent(fileName)
|
||||
let copied = this.copyFile(at: url, to: newPath)
|
||||
if(copied) {
|
||||
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .image))
|
||||
}
|
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app
|
||||
if index == (content.attachments?.count)! - 1 {
|
||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
|
||||
userDefaults?.synchronize()
|
||||
this.redirectToHostApp(type: .media)
|
||||
}
|
||||
|
||||
} else {
|
||||
self?.dismissWithError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleVideos (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
||||
attachment.loadItem(forTypeIdentifier: videoContentType, options: nil) { [weak self] data, error in
|
||||
|
||||
if error == nil, let url = data as? URL, let this = self {
|
||||
|
||||
// Always copy
|
||||
let fileName = this.getFileName(from: url, type: .video)
|
||||
let newPath = FileManager.default
|
||||
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
|
||||
.appendingPathComponent(fileName)
|
||||
let copied = this.copyFile(at: url, to: newPath)
|
||||
if(copied) {
|
||||
guard let sharedFile = this.getSharedMediaFile(forVideo: newPath) else {
|
||||
return
|
||||
}
|
||||
this.sharedMedia.append(sharedFile)
|
||||
}
|
||||
|
||||
// If this is the last item, save imagesData in userDefaults and redirect to host app
|
||||
if index == (content.attachments?.count)! - 1 {
|
||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
|
||||
userDefaults?.synchronize()
|
||||
this.redirectToHostApp(type: .media)
|
||||
}
|
||||
|
||||
} else {
|
||||
self?.dismissWithError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func handleFiles (content: NSExtensionItem, attachment: NSItemProvider, index: Int) {
|
||||
attachment.loadItem(forTypeIdentifier: fileURLType, options: nil) { [weak self] data, error in
|
||||
|
||||
if error == nil, let url = data as? URL, let this = self {
|
||||
|
||||
// Always copy
|
||||
let fileName = this.getFileName(from :url, type: .file)
|
||||
let newPath = FileManager.default
|
||||
.containerURL(forSecurityApplicationGroupIdentifier: this.appGroupId)!
|
||||
.appendingPathComponent(fileName)
|
||||
let copied = this.copyFile(at: url, to: newPath)
|
||||
if (copied) {
|
||||
this.sharedMedia.append(SharedMediaFile(path: newPath.absoluteString, thumbnail: nil, duration: nil, type: .file))
|
||||
}
|
||||
|
||||
if index == (content.attachments?.count)! - 1 {
|
||||
let userDefaults = UserDefaults(suiteName: this.appGroupId)
|
||||
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
|
||||
userDefaults?.synchronize()
|
||||
this.redirectToHostApp(type: .file)
|
||||
}
|
||||
|
||||
} else {
|
||||
self?.dismissWithError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func dismissWithError() {
|
||||
TwakeLogger.shared.log(message: "[ERROR] Error loading data!")
|
||||
let alert = UIAlertController(title: "Error", message: "Error loading data", preferredStyle: .alert)
|
||||
|
||||
let action = UIAlertAction(title: "Error", style: .cancel) { _ in
|
||||
self.dismiss(animated: true, completion: nil)
|
||||
}
|
||||
|
||||
alert.addAction(action)
|
||||
present(alert, animated: true, completion: nil)
|
||||
extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
|
||||
}
|
||||
|
||||
private func redirectToHostApp(type: RedirectType) {
|
||||
// ids may not loaded yet so we need loadIds here too
|
||||
loadIds();
|
||||
let url = URL(string: "ShareMedia-\(hostAppBundleIdentifier)://dataUrl=\(sharedKey)#\(type)")
|
||||
var responder = self as UIResponder?
|
||||
let selectorOpenURL = sel_registerName("openURL:")
|
||||
|
||||
while (responder != nil) {
|
||||
if (responder?.responds(to: selectorOpenURL))! {
|
||||
let _ = responder?.perform(selectorOpenURL, with: url)
|
||||
}
|
||||
responder = responder!.next
|
||||
}
|
||||
extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
|
||||
}
|
||||
|
||||
enum RedirectType {
|
||||
case media
|
||||
case text
|
||||
case file
|
||||
}
|
||||
|
||||
func getExtension(from url: URL, type: SharedMediaType) -> 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"
|
||||
}
|
||||
}
|
||||
return ex ?? "Unknown"
|
||||
}
|
||||
|
||||
func getFileName(from url: URL, type: SharedMediaType) -> 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)
|
||||
} catch (let error) {
|
||||
TwakeLogger.shared.log(message: "Cannot copy item at \(srcURL) to \(dstURL): \(error)")
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private func getSharedMediaFile(forVideo: URL) -> SharedMediaFile? {
|
||||
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 SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video)
|
||||
}
|
||||
|
||||
var saved = false
|
||||
let assetImgGenerate = AVAssetImageGenerator(asset: asset)
|
||||
assetImgGenerate.appliesPreferredTrackTransform = true
|
||||
// let scale = UIScreen.main.scale
|
||||
assetImgGenerate.maximumSize = CGSize(width: 360, height: 360)
|
||||
do {
|
||||
let img = try assetImgGenerate.copyCGImage(at: CMTimeMakeWithSeconds(600, preferredTimescale: Int32(1.0)), actualTime: nil)
|
||||
try UIImage.pngData(UIImage(cgImage: img))()?.write(to: thumbnailPath)
|
||||
saved = true
|
||||
} catch {
|
||||
saved = false
|
||||
}
|
||||
|
||||
return saved ? SharedMediaFile(path: forVideo.absoluteString, thumbnail: thumbnailPath.absoluteString, duration: duration, type: .video) : nil
|
||||
|
||||
}
|
||||
|
||||
private func getThumbnailPath(for url: URL) -> URL {
|
||||
let fileName = Data(url.lastPathComponent.utf8).base64EncodedString().replacingOccurrences(of: "==", with: "")
|
||||
let path = FileManager.default
|
||||
.containerURL(forSecurityApplicationGroupIdentifier: appGroupId)!
|
||||
.appendingPathComponent("\(fileName).jpg")
|
||||
return path
|
||||
}
|
||||
|
||||
class SharedMediaFile: Codable {
|
||||
var path: String; // can be image, video or url path. It can also be text content
|
||||
var thumbnail: String?; // video thumbnail
|
||||
var duration: Double?; // video duration in milliseconds
|
||||
var type: SharedMediaType;
|
||||
|
||||
|
||||
init(path: String, thumbnail: String?, duration: Double?, type: SharedMediaType) {
|
||||
self.path = path
|
||||
self.thumbnail = thumbnail
|
||||
self.duration = duration
|
||||
self.type = type
|
||||
}
|
||||
|
||||
// Debug method to print out SharedMediaFile details in the console
|
||||
func toString() {
|
||||
TwakeLogger.shared.log(message: "[SharedMediaFile] \n\tpath: \(self.path)\n\tthumbnail: \(self.thumbnail)\n\tduration: \(self.duration)\n\ttype: \(self.type)")
|
||||
}
|
||||
}
|
||||
|
||||
enum SharedMediaType: Int, Codable {
|
||||
case image
|
||||
case video
|
||||
case file
|
||||
}
|
||||
|
||||
func toData(data: [SharedMediaFile]) -> Data {
|
||||
let encodedData = try? JSONEncoder().encode(data)
|
||||
return encodedData!
|
||||
}
|
||||
}
|
||||
|
||||
extension Array {
|
||||
subscript (safe index: UInt) -> Element? {
|
||||
return Int(index) < count ? self[Int(index)] : nil
|
||||
}
|
||||
class ShareViewController: RSIShareViewController {
|
||||
}
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:model/upload/file_info.dart';
|
||||
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||
import 'package:tmail_ui_user/features/composer/presentation/extensions/file_extension.dart';
|
||||
|
||||
extension SharedMediaFileExtension on SharedMediaFile {
|
||||
File toFile() {
|
||||
if (PlatformInfo.isIOS) {
|
||||
final pathFile = type == SharedMediaType.FILE
|
||||
? path.toString().replaceAll('file:/', '').replaceAll('%20', ' ')
|
||||
: path.toString().replaceAll('%20', ' ');
|
||||
return File(pathFile);
|
||||
} else {
|
||||
return File(path);
|
||||
}
|
||||
}
|
||||
File toFile() => File(path);
|
||||
|
||||
FileInfo toFileInfo({bool? isShared}) => toFile().toFileInfo(isInline: type == SharedMediaType.IMAGE, isShared: isShared);
|
||||
FileInfo toFileInfo({bool? isShared}) =>
|
||||
toFile().toFileInfo(
|
||||
isInline: type == SharedMediaType.image,
|
||||
isShared: isShared,
|
||||
);
|
||||
}
|
||||
@@ -1,12 +1,7 @@
|
||||
import 'package:core/utils/platform_info.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_downloader/flutter_downloader.dart';
|
||||
import 'package:get/get.dart';
|
||||
import 'package:jmap_dart_client/jmap/core/session/session.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/email/email_content.dart';
|
||||
import 'package:model/email/email_content_type.dart';
|
||||
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
|
||||
import 'package:tmail_ui_user/features/caching/config/hive_cache_config.dart';
|
||||
import 'package:tmail_ui_user/features/cleanup/domain/model/cleanup_rule.dart';
|
||||
@@ -45,7 +40,7 @@ class HomeController extends ReloadableController {
|
||||
void onInit() {
|
||||
if (PlatformInfo.isMobile) {
|
||||
_initFlutterDownloader();
|
||||
_registerReceivingSharingIntent();
|
||||
_registerReceivingFileSharing();
|
||||
}
|
||||
if (PlatformInfo.isIOS) {
|
||||
_registerNotificationClickOnIOS();
|
||||
@@ -85,20 +80,8 @@ class HomeController extends ReloadableController {
|
||||
], eagerError: true).then((_) => getAuthenticatedAccountAction());
|
||||
}
|
||||
|
||||
void _registerReceivingSharingIntent() {
|
||||
_emailReceiveManager.receivingSharingStream.listen((uri) {
|
||||
if (uri != null) {
|
||||
if (GetUtils.isEmail(uri.path)) {
|
||||
_emailReceiveManager.setPendingEmailAddress(EmailAddress(null, uri.path));
|
||||
} else if (uri.scheme == "file") {
|
||||
_emailReceiveManager.setPendingFileInfo([SharedMediaFile(uri.path, null, null, SharedMediaType.FILE)]);
|
||||
} else {
|
||||
_emailReceiveManager.setPendingEmailContent(EmailContent(EmailContentType.textPlain, Uri.decodeComponent(uri.path)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
_emailReceiveManager.receivingFileSharingStream.listen(_emailReceiveManager.setPendingFileInfo);
|
||||
void _registerReceivingFileSharing() {
|
||||
_emailReceiveManager.registerReceivingFileSharingStreamWhileAppClosed();
|
||||
}
|
||||
|
||||
void _registerNotificationClickOnIOS() {
|
||||
|
||||
+85
-32
@@ -25,6 +25,7 @@ import 'package:jmap_dart_client/jmap/mail/mailbox/mailbox.dart';
|
||||
import 'package:jmap_dart_client/jmap/mail/vacation/vacation_response.dart';
|
||||
import 'package:model/model.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||
import 'package:rxdart/transformers.dart';
|
||||
import 'package:tmail_ui_user/features/base/action/ui_action.dart';
|
||||
import 'package:tmail_ui_user/features/base/reloadable/reloadable_controller.dart';
|
||||
@@ -241,11 +242,8 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
||||
ComposerArguments? composerArguments;
|
||||
List<Identity>? _identities;
|
||||
ScrollController? listSearchFilterScrollController;
|
||||
|
||||
late StreamSubscription _emailAddressStreamSubscription;
|
||||
late StreamSubscription _emailContentStreamSubscription;
|
||||
late StreamSubscription _fileReceiveManagerStreamSubscription;
|
||||
|
||||
StreamSubscription? _pendingSharedFileInfoSubscription;
|
||||
StreamSubscription? _receivingFileSharingStreamSubscription;
|
||||
StreamSubscription? _currentEmailIdInNotificationIOSStreamSubscription;
|
||||
|
||||
final StreamController<Either<Failure, Success>> _progressStateController =
|
||||
@@ -288,6 +286,9 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
||||
|
||||
@override
|
||||
void onInit() {
|
||||
if (PlatformInfo.isMobile) {
|
||||
_registerReceivingFileSharingStream();
|
||||
}
|
||||
_registerStreamListener();
|
||||
BackButtonInterceptor.add(_onBackButtonInterceptor, name: AppRoutes.dashboard);
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
@@ -301,9 +302,6 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
||||
if (PlatformInfo.isWeb) {
|
||||
listSearchFilterScrollController = ScrollController();
|
||||
}
|
||||
_registerPendingEmailAddress();
|
||||
_registerPendingEmailContents();
|
||||
_registerPendingFileInfo();
|
||||
if (PlatformInfo.isIOS) {
|
||||
_registerPendingCurrentEmailIdInNotification();
|
||||
}
|
||||
@@ -454,31 +452,85 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
||||
}
|
||||
}
|
||||
|
||||
void _registerPendingEmailAddress() {
|
||||
_emailAddressStreamSubscription =
|
||||
_emailReceiveManager.pendingEmailAddressInfo.stream.listen((emailAddress) {
|
||||
if (emailAddress?.email?.isNotEmpty == true) {
|
||||
goToComposer(ComposerArguments.fromEmailAddress(emailAddress!));
|
||||
}
|
||||
});
|
||||
void _registerReceivingFileSharingStream() {
|
||||
_receivingFileSharingStreamSubscription = _emailReceiveManager
|
||||
.receivingFileSharingStream
|
||||
.listen(
|
||||
_emailReceiveManager.setPendingFileInfo,
|
||||
onError: (err) {
|
||||
logError('MailboxDashBoardController::_registerReceivingFileSharingStream::receivingFileSharingStream:Exception = $err');
|
||||
},
|
||||
);
|
||||
|
||||
_pendingSharedFileInfoSubscription = _emailReceiveManager
|
||||
.pendingSharedFileInfo
|
||||
.listen(
|
||||
_handleReceivingFileSharing,
|
||||
onError: (err) {
|
||||
logError('MailboxDashBoardController::_registerReceivingFileSharingStream::pendingSharedFileInfo:Exception = $err');
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
void _registerPendingEmailContents() {
|
||||
_emailContentStreamSubscription =
|
||||
_emailReceiveManager.pendingEmailContentInfo.stream.listen((emailContent) {
|
||||
if (emailContent?.content.isNotEmpty == true) {
|
||||
goToComposer(ComposerArguments.fromContentShared([emailContent!].asHtmlString));
|
||||
}
|
||||
});
|
||||
void _handleReceivingFileSharing(List<SharedMediaFile> listSharedMediaFile) {
|
||||
log('MailboxDashBoardController::_handleReceivingFileSharing: LIST_LENGTH = ${listSharedMediaFile.length}');
|
||||
if (listSharedMediaFile.isEmpty) return;
|
||||
|
||||
for (var file in listSharedMediaFile) {
|
||||
log('MailboxDashBoardController::_handleReceivingFileSharing:SharedMediaFile = ${file.toMap()}');
|
||||
}
|
||||
|
||||
void _registerPendingFileInfo() {
|
||||
_fileReceiveManagerStreamSubscription =
|
||||
_emailReceiveManager.pendingFileInfo.stream.listen((listFile) {
|
||||
if (listFile.isNotEmpty) {
|
||||
goToComposer(ComposerArguments.fromFileShared(listFile));
|
||||
if (listSharedMediaFile.length == 1) {
|
||||
final sharedMediaFile = listSharedMediaFile.first;
|
||||
if (sharedMediaFile.path.trim().isEmpty) return;
|
||||
|
||||
switch (sharedMediaFile.type) {
|
||||
case SharedMediaType.image:
|
||||
case SharedMediaType.video:
|
||||
case SharedMediaType.file:
|
||||
goToComposer(
|
||||
ComposerArguments.fromFileShared([sharedMediaFile]),
|
||||
);
|
||||
break;
|
||||
case SharedMediaType.text:
|
||||
if (sharedMediaFile.mimeType == Constant.textVCardMimeType) {
|
||||
goToComposer(
|
||||
ComposerArguments.fromFileShared([sharedMediaFile]),
|
||||
);
|
||||
} else if (sharedMediaFile.mimeType == Constant.textPlainMimeType) {
|
||||
goToComposer(
|
||||
ComposerArguments.fromContentShared(sharedMediaFile.path.trim()),
|
||||
);
|
||||
}
|
||||
});
|
||||
break;
|
||||
case SharedMediaType.url:
|
||||
if (sharedMediaFile.path.startsWith(RouteUtils.mailtoPrefix)) {
|
||||
final navigationRouter = RouteUtils.generateNavigationRouterFromMailtoLink(sharedMediaFile.path);
|
||||
goToComposer(
|
||||
ComposerArguments.fromMailtoUri(
|
||||
listEmailAddress: navigationRouter.listEmailAddress,
|
||||
subject: navigationRouter.subject,
|
||||
body: navigationRouter.body,
|
||||
),
|
||||
);
|
||||
}
|
||||
break;
|
||||
case SharedMediaType.mailto:
|
||||
if (EmailUtils.isEmailAddressValid(sharedMediaFile.path)) {
|
||||
goToComposer(
|
||||
ComposerArguments.fromEmailAddress(
|
||||
EmailAddress(null, sharedMediaFile.path),
|
||||
),
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
goToComposer(
|
||||
ComposerArguments.fromFileShared(listSharedMediaFile),
|
||||
);
|
||||
}
|
||||
|
||||
void _registerPendingCurrentEmailIdInNotification() {
|
||||
@@ -2861,14 +2913,15 @@ class MailboxDashBoardController extends ReloadableController with UserSettingPo
|
||||
if (PlatformInfo.isWeb) {
|
||||
listSearchFilterScrollController?.dispose();
|
||||
}
|
||||
_emailReceiveManager.closeEmailReceiveManagerStream();
|
||||
if (PlatformInfo.isIOS) {
|
||||
_iosNotificationManager?.dispose();
|
||||
_currentEmailIdInNotificationIOSStreamSubscription?.cancel();
|
||||
}
|
||||
_emailAddressStreamSubscription.cancel();
|
||||
_emailContentStreamSubscription.cancel();
|
||||
_fileReceiveManagerStreamSubscription.cancel();
|
||||
if (PlatformInfo.isMobile) {
|
||||
_pendingSharedFileInfoSubscription?.cancel();
|
||||
_receivingFileSharingStreamSubscription?.cancel();
|
||||
_emailReceiveManager.closeEmailReceiveManagerStream();
|
||||
}
|
||||
_progressStateController.close();
|
||||
_refreshActionEventController.close();
|
||||
_notificationManager.closeStream();
|
||||
|
||||
@@ -1,75 +1,38 @@
|
||||
|
||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||
import 'package:model/email/email_content.dart';
|
||||
import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
||||
import 'package:rxdart/rxdart.dart';
|
||||
|
||||
class EmailReceiveManager {
|
||||
BehaviorSubject<List<SharedMediaFile>> _pendingSharedFileInfo =
|
||||
BehaviorSubject.seeded(List.empty(growable: true));
|
||||
BehaviorSubject<List<SharedMediaFile>> get pendingSharedFileInfo =>
|
||||
_pendingSharedFileInfo;
|
||||
|
||||
BehaviorSubject<EmailAddress?> _pendingEmailAddressInfo = BehaviorSubject.seeded(null);
|
||||
BehaviorSubject<EmailAddress?> get pendingEmailAddressInfo => _pendingEmailAddressInfo;
|
||||
Stream<List<SharedMediaFile>> get receivingFileSharingStream =>
|
||||
ReceiveSharingIntent.instance.getMediaStream();
|
||||
|
||||
BehaviorSubject<EmailContent?> _pendingEmailContentInfo = BehaviorSubject.seeded(null);
|
||||
BehaviorSubject<EmailContent?> get pendingEmailContentInfo => _pendingEmailContentInfo;
|
||||
void registerReceivingFileSharingStreamWhileAppClosed() {
|
||||
ReceiveSharingIntent.instance.getInitialMedia().then((value) {
|
||||
setPendingFileInfo(value);
|
||||
|
||||
BehaviorSubject<List<SharedMediaFile>> _pendingFileInfo = BehaviorSubject.seeded(List.empty(growable: true));
|
||||
BehaviorSubject<List<SharedMediaFile>> get pendingFileInfo => _pendingFileInfo;
|
||||
|
||||
Stream<Uri?> get receivingSharingStream {
|
||||
return Rx.merge([
|
||||
Stream.fromFuture(ReceiveSharingIntent.getInitialTextAsUri()),
|
||||
ReceiveSharingIntent.getTextStreamAsUri()
|
||||
]);
|
||||
}
|
||||
Stream<List<SharedMediaFile>> get receivingFileSharingStream {
|
||||
return Rx.merge([
|
||||
Stream.fromFuture(ReceiveSharingIntent.getInitialMedia()),
|
||||
ReceiveSharingIntent.getMediaStream()
|
||||
]);
|
||||
}
|
||||
|
||||
void setPendingEmailAddress(EmailAddress emailAddress) async {
|
||||
_clearPendingEmailAddress();
|
||||
_pendingEmailAddressInfo.add(emailAddress);
|
||||
}
|
||||
|
||||
void setPendingEmailContent(EmailContent emailContent) async {
|
||||
_clearPendingEmailContent();
|
||||
_pendingEmailContentInfo.add(emailContent);
|
||||
}
|
||||
|
||||
void _clearPendingEmailContent() {
|
||||
if (_pendingEmailContentInfo.isClosed) {
|
||||
_pendingEmailContentInfo = BehaviorSubject.seeded(null);
|
||||
} else {
|
||||
_pendingEmailContentInfo.add(null);
|
||||
}
|
||||
}
|
||||
|
||||
void _clearPendingEmailAddress() {
|
||||
if(_pendingEmailAddressInfo.isClosed) {
|
||||
_pendingEmailAddressInfo = BehaviorSubject.seeded(null);
|
||||
} else {
|
||||
_pendingEmailAddressInfo.add(null);
|
||||
}
|
||||
ReceiveSharingIntent.instance.reset();
|
||||
});
|
||||
}
|
||||
|
||||
void closeEmailReceiveManagerStream() {
|
||||
_pendingEmailAddressInfo.close();
|
||||
_pendingEmailContentInfo.close();
|
||||
_pendingFileInfo.close();
|
||||
_pendingSharedFileInfo.close();
|
||||
}
|
||||
|
||||
void setPendingFileInfo(List<SharedMediaFile> list) async {
|
||||
void setPendingFileInfo(List<SharedMediaFile> list) {
|
||||
_clearPendingFileInfo();
|
||||
_pendingFileInfo.add(list);
|
||||
_pendingSharedFileInfo.add(list);
|
||||
}
|
||||
|
||||
void _clearPendingFileInfo() {
|
||||
if(_pendingFileInfo.isClosed) {
|
||||
_pendingFileInfo = BehaviorSubject.seeded(List.empty(growable: true));
|
||||
if(_pendingSharedFileInfo.isClosed) {
|
||||
_pendingSharedFileInfo = BehaviorSubject.seeded(List.empty(growable: true));
|
||||
} else {
|
||||
_pendingFileInfo.add(List.empty(growable: true));
|
||||
_pendingSharedFileInfo.add(List.empty(growable: true));
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1758,11 +1758,11 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: master
|
||||
resolved-ref: f23f7fb0fad25ae80a88350ad8654851f1ee682f
|
||||
ref: main
|
||||
resolved-ref: b388eb837bd1256a9623a8cd0a62cfc21e9f51cf
|
||||
url: "https://github.com/linagora/receive_sharing_intent.git"
|
||||
source: git
|
||||
version: "1.4.5"
|
||||
version: "1.8.1"
|
||||
rich_text_composer:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ dependencies:
|
||||
receive_sharing_intent:
|
||||
git:
|
||||
url: https://github.com/linagora/receive_sharing_intent.git
|
||||
ref: master
|
||||
ref: main
|
||||
|
||||
flutter_appauth_web:
|
||||
git:
|
||||
|
||||
+1
-3
@@ -347,9 +347,7 @@ void main() {
|
||||
setUp(() {
|
||||
getEmailsInMailboxInteractor = MockGetEmailsInMailboxInteractor();
|
||||
|
||||
when(emailReceiveManager.pendingEmailAddressInfo).thenAnswer((_) => BehaviorSubject.seeded(null));
|
||||
when(emailReceiveManager.pendingEmailContentInfo).thenAnswer((_) => BehaviorSubject.seeded(null));
|
||||
when(emailReceiveManager.pendingFileInfo).thenAnswer((_) => BehaviorSubject.seeded([]));
|
||||
when(emailReceiveManager.pendingSharedFileInfo).thenAnswer((_) => BehaviorSubject.seeded([]));
|
||||
|
||||
Get.put(mailboxDashboardController);
|
||||
mailboxDashboardController.onReady();
|
||||
|
||||
+1
-3
@@ -306,9 +306,7 @@ void main() {
|
||||
Get.put<GetAllIdentitiesInteractor>(getAllIdentitiesInteractor);
|
||||
Get.put<RemoveComposerCacheOnWebInteractor>(removeComposerCacheOnWebInteractor);
|
||||
|
||||
when(emailReceiveManager.pendingEmailAddressInfo).thenAnswer((_) => BehaviorSubject.seeded(null));
|
||||
when(emailReceiveManager.pendingEmailContentInfo).thenAnswer((_) => BehaviorSubject.seeded(null));
|
||||
when(emailReceiveManager.pendingFileInfo).thenAnswer((_) => BehaviorSubject.seeded([]));
|
||||
when(emailReceiveManager.pendingSharedFileInfo).thenAnswer((_) => BehaviorSubject.seeded([]));
|
||||
|
||||
searchController = SearchController(
|
||||
quickSearchEmailInteractor,
|
||||
|
||||
Reference in New Issue
Block a user