mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-07 01:15:50 -06:00
Added ios support for receive_sharing_intent, some consistency fixes and bug fixes
This commit is contained in:
@@ -46,6 +46,9 @@ PODS:
|
|||||||
- Flutter
|
- Flutter
|
||||||
- flutter_native_splash (0.0.1):
|
- flutter_native_splash (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- fluttertoast (0.0.2):
|
||||||
|
- Flutter
|
||||||
|
- Toast
|
||||||
- FMDB (2.7.5):
|
- FMDB (2.7.5):
|
||||||
- FMDB/standard (= 2.7.5)
|
- FMDB/standard (= 2.7.5)
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
@@ -62,15 +65,20 @@ PODS:
|
|||||||
- permission_handler_apple (9.0.4):
|
- permission_handler_apple (9.0.4):
|
||||||
- Flutter
|
- Flutter
|
||||||
- ReachabilitySwift (5.0.0)
|
- ReachabilitySwift (5.0.0)
|
||||||
|
- receive_sharing_intent (0.0.1):
|
||||||
|
- Flutter
|
||||||
- SDWebImage (5.13.5):
|
- SDWebImage (5.13.5):
|
||||||
- SDWebImage/Core (= 5.13.5)
|
- SDWebImage/Core (= 5.13.5)
|
||||||
- SDWebImage/Core (5.13.5)
|
- SDWebImage/Core (5.13.5)
|
||||||
|
- share_plus (0.0.1):
|
||||||
|
- Flutter
|
||||||
- shared_preferences_ios (0.0.1):
|
- shared_preferences_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- sqflite (0.0.2):
|
- sqflite (0.0.2):
|
||||||
- Flutter
|
- Flutter
|
||||||
- FMDB (>= 2.7.5)
|
- FMDB (>= 2.7.5)
|
||||||
- SwiftyGif (5.4.3)
|
- SwiftyGif (5.4.3)
|
||||||
|
- Toast (4.0.0)
|
||||||
- url_launcher_ios (0.0.1):
|
- url_launcher_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- WeScan (1.7.0)
|
- WeScan (1.7.0)
|
||||||
@@ -83,12 +91,15 @@ DEPENDENCIES:
|
|||||||
- Flutter (from `Flutter`)
|
- Flutter (from `Flutter`)
|
||||||
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
- flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`)
|
||||||
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
- flutter_native_splash (from `.symlinks/plugins/flutter_native_splash/ios`)
|
||||||
|
- fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
|
||||||
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
- integration_test (from `.symlinks/plugins/integration_test/ios`)
|
||||||
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
|
- local_auth_ios (from `.symlinks/plugins/local_auth_ios/ios`)
|
||||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||||
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
|
||||||
- pdfx (from `.symlinks/plugins/pdfx/ios`)
|
- pdfx (from `.symlinks/plugins/pdfx/ios`)
|
||||||
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
|
||||||
|
- receive_sharing_intent (from `.symlinks/plugins/receive_sharing_intent/ios`)
|
||||||
|
- share_plus (from `.symlinks/plugins/share_plus/ios`)
|
||||||
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
- shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||||
@@ -101,6 +112,7 @@ SPEC REPOS:
|
|||||||
- ReachabilitySwift
|
- ReachabilitySwift
|
||||||
- SDWebImage
|
- SDWebImage
|
||||||
- SwiftyGif
|
- SwiftyGif
|
||||||
|
- Toast
|
||||||
- WeScan
|
- WeScan
|
||||||
|
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
@@ -118,6 +130,8 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
:path: ".symlinks/plugins/flutter_keyboard_visibility/ios"
|
||||||
flutter_native_splash:
|
flutter_native_splash:
|
||||||
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
:path: ".symlinks/plugins/flutter_native_splash/ios"
|
||||||
|
fluttertoast:
|
||||||
|
:path: ".symlinks/plugins/fluttertoast/ios"
|
||||||
integration_test:
|
integration_test:
|
||||||
:path: ".symlinks/plugins/integration_test/ios"
|
:path: ".symlinks/plugins/integration_test/ios"
|
||||||
local_auth_ios:
|
local_auth_ios:
|
||||||
@@ -130,6 +144,10 @@ EXTERNAL SOURCES:
|
|||||||
:path: ".symlinks/plugins/pdfx/ios"
|
:path: ".symlinks/plugins/pdfx/ios"
|
||||||
permission_handler_apple:
|
permission_handler_apple:
|
||||||
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
:path: ".symlinks/plugins/permission_handler_apple/ios"
|
||||||
|
receive_sharing_intent:
|
||||||
|
:path: ".symlinks/plugins/receive_sharing_intent/ios"
|
||||||
|
share_plus:
|
||||||
|
:path: ".symlinks/plugins/share_plus/ios"
|
||||||
shared_preferences_ios:
|
shared_preferences_ios:
|
||||||
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
:path: ".symlinks/plugins/shared_preferences_ios/ios"
|
||||||
sqflite:
|
sqflite:
|
||||||
@@ -147,6 +165,7 @@ SPEC CHECKSUMS:
|
|||||||
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
|
||||||
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
flutter_keyboard_visibility: 0339d06371254c3eb25eeb90ba8d17dca8f9c069
|
||||||
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
flutter_native_splash: 52501b97d1c0a5f898d687f1646226c1f93c56ef
|
||||||
|
fluttertoast: 74526702fea2c060ea55dde75895b7e1bde1c86b
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
|
integration_test: a1e7d09bd98eca2fc37aefd79d4f41ad37bdbbe5
|
||||||
local_auth_ios: 0d333dde7780f669e66f19d2ff6005f3ea84008d
|
local_auth_ios: 0d333dde7780f669e66f19d2ff6005f3ea84008d
|
||||||
@@ -155,10 +174,13 @@ SPEC CHECKSUMS:
|
|||||||
pdfx: 7b876b09de8b7a0bf444a4f82b439ffcff4ee1ec
|
pdfx: 7b876b09de8b7a0bf444a4f82b439ffcff4ee1ec
|
||||||
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce
|
||||||
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825
|
||||||
|
receive_sharing_intent: c0d87310754e74c0f9542947e7cbdf3a0335a3b1
|
||||||
SDWebImage: 23d714cd599354ee7906dbae26dff89b421c4370
|
SDWebImage: 23d714cd599354ee7906dbae26dff89b421c4370
|
||||||
|
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68
|
||||||
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
|
shared_preferences_ios: 548a61f8053b9b8a49ac19c1ffbc8b92c50d68ad
|
||||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||||
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
|
SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780
|
||||||
|
Toast: 91b396c56ee72a5790816f40d3a94dd357abc196
|
||||||
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
|
url_launcher_ios: 839c58cdb4279282219f5e248c3321761ff3c4de
|
||||||
WeScan: fed582f6c38014d529afb5aa9ffd1bad38fc72b7
|
WeScan: fed582f6c38014d529afb5aa9ffd1bad38fc72b7
|
||||||
|
|
||||||
|
|||||||
@@ -3,12 +3,15 @@
|
|||||||
archiveVersion = 1;
|
archiveVersion = 1;
|
||||||
classes = {
|
classes = {
|
||||||
};
|
};
|
||||||
objectVersion = 50;
|
objectVersion = 51;
|
||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||||
|
4D0C7954292C15240064EE78 /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D0C7953292C15240064EE78 /* ShareViewController.swift */; };
|
||||||
|
4D0C7957292C15240064EE78 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4D0C7955292C15240064EE78 /* MainInterface.storyboard */; };
|
||||||
|
4D0C795B292C15240064EE78 /* receive_sharing_intent.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 4D0C7951292C15240064EE78 /* receive_sharing_intent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
@@ -16,7 +19,28 @@
|
|||||||
B8F579F7EE511C92B2614EE2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40BF6B81A87C86D22CDB775A /* Pods_Runner.framework */; };
|
B8F579F7EE511C92B2614EE2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 40BF6B81A87C86D22CDB775A /* Pods_Runner.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
4D0C7959292C15240064EE78 /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 4D0C7950292C15240064EE78;
|
||||||
|
remoteInfo = receive_sharing_intent;
|
||||||
|
};
|
||||||
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
4D0C795C292C15250064EE78 /* Embed Foundation Extensions */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 13;
|
||||||
|
files = (
|
||||||
|
4D0C795B292C15240064EE78 /* receive_sharing_intent.appex in Embed Foundation Extensions */,
|
||||||
|
);
|
||||||
|
name = "Embed Foundation Extensions";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -34,6 +58,12 @@
|
|||||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||||
40BF6B81A87C86D22CDB775A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
40BF6B81A87C86D22CDB775A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
4D0C7951292C15240064EE78 /* receive_sharing_intent.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = receive_sharing_intent.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
4D0C7953292C15240064EE78 /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||||
|
4D0C7956292C15240064EE78 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||||
|
4D0C7958292C15240064EE78 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
|
4D0C7961292C196E0064EE78 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||||
|
4D0C7962292C19960064EE78 /* receive_sharing_intent.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = receive_sharing_intent.entitlements; sourceTree = "<group>"; };
|
||||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||||
@@ -50,6 +80,13 @@
|
|||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
4D0C794E292C15240064EE78 /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
97C146EB1CF9000F007C117D /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -61,6 +98,17 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
4D0C7952292C15240064EE78 /* receive_sharing_intent */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4D0C7962292C19960064EE78 /* receive_sharing_intent.entitlements */,
|
||||||
|
4D0C7953292C15240064EE78 /* ShareViewController.swift */,
|
||||||
|
4D0C7955292C15240064EE78 /* MainInterface.storyboard */,
|
||||||
|
4D0C7958292C15240064EE78 /* Info.plist */,
|
||||||
|
);
|
||||||
|
path = receive_sharing_intent;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -77,6 +125,7 @@
|
|||||||
children = (
|
children = (
|
||||||
9740EEB11CF90186004384FC /* Flutter */,
|
9740EEB11CF90186004384FC /* Flutter */,
|
||||||
97C146F01CF9000F007C117D /* Runner */,
|
97C146F01CF9000F007C117D /* Runner */,
|
||||||
|
4D0C7952292C15240064EE78 /* receive_sharing_intent */,
|
||||||
97C146EF1CF9000F007C117D /* Products */,
|
97C146EF1CF9000F007C117D /* Products */,
|
||||||
E525DE4999AE527627D97DCA /* Pods */,
|
E525DE4999AE527627D97DCA /* Pods */,
|
||||||
FB6F7F4A953DAAA3FFE794E6 /* Frameworks */,
|
FB6F7F4A953DAAA3FFE794E6 /* Frameworks */,
|
||||||
@@ -87,6 +136,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
97C146EE1CF9000F007C117D /* Runner.app */,
|
97C146EE1CF9000F007C117D /* Runner.app */,
|
||||||
|
4D0C7951292C15240064EE78 /* receive_sharing_intent.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -94,6 +144,7 @@
|
|||||||
97C146F01CF9000F007C117D /* Runner */ = {
|
97C146F01CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
4D0C7961292C196E0064EE78 /* Runner.entitlements */,
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
97C146FA1CF9000F007C117D /* Main.storyboard */,
|
||||||
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
97C146FD1CF9000F007C117D /* Assets.xcassets */,
|
||||||
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
|
||||||
@@ -113,7 +164,6 @@
|
|||||||
9F0882A26646B3A4713EAA3B /* Pods-Runner.release.xcconfig */,
|
9F0882A26646B3A4713EAA3B /* Pods-Runner.release.xcconfig */,
|
||||||
895AB075C3F1E3E87F6C3D1A /* Pods-Runner.profile.xcconfig */,
|
895AB075C3F1E3E87F6C3D1A /* Pods-Runner.profile.xcconfig */,
|
||||||
);
|
);
|
||||||
name = Pods;
|
|
||||||
path = Pods;
|
path = Pods;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
@@ -128,6 +178,23 @@
|
|||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
4D0C7950292C15240064EE78 /* receive_sharing_intent */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 4D0C7960292C15250064EE78 /* Build configuration list for PBXNativeTarget "receive_sharing_intent" */;
|
||||||
|
buildPhases = (
|
||||||
|
4D0C794D292C15240064EE78 /* Sources */,
|
||||||
|
4D0C794E292C15240064EE78 /* Frameworks */,
|
||||||
|
4D0C794F292C15240064EE78 /* Resources */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = receive_sharing_intent;
|
||||||
|
productName = receive_sharing_intent;
|
||||||
|
productReference = 4D0C7951292C15240064EE78 /* receive_sharing_intent.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
|
};
|
||||||
97C146ED1CF9000F007C117D /* Runner */ = {
|
97C146ED1CF9000F007C117D /* Runner */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||||
@@ -140,10 +207,12 @@
|
|||||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||||
13B6B31A3992BA65B73408A6 /* [CP] Embed Pods Frameworks */,
|
13B6B31A3992BA65B73408A6 /* [CP] Embed Pods Frameworks */,
|
||||||
|
4D0C795C292C15250064EE78 /* Embed Foundation Extensions */,
|
||||||
);
|
);
|
||||||
buildRules = (
|
buildRules = (
|
||||||
);
|
);
|
||||||
dependencies = (
|
dependencies = (
|
||||||
|
4D0C795A292C15240064EE78 /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = Runner;
|
name = Runner;
|
||||||
productName = Runner;
|
productName = Runner;
|
||||||
@@ -156,9 +225,13 @@
|
|||||||
97C146E61CF9000F007C117D /* Project object */ = {
|
97C146E61CF9000F007C117D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
|
LastSwiftUpdateCheck = 1400;
|
||||||
LastUpgradeCheck = 1300;
|
LastUpgradeCheck = 1300;
|
||||||
ORGANIZATIONNAME = "";
|
ORGANIZATIONNAME = "";
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
|
4D0C7950292C15240064EE78 = {
|
||||||
|
CreatedOnToolsVersion = 14.0.1;
|
||||||
|
};
|
||||||
97C146ED1CF9000F007C117D = {
|
97C146ED1CF9000F007C117D = {
|
||||||
CreatedOnToolsVersion = 7.3.1;
|
CreatedOnToolsVersion = 7.3.1;
|
||||||
LastSwiftMigration = 1100;
|
LastSwiftMigration = 1100;
|
||||||
@@ -179,11 +252,20 @@
|
|||||||
projectRoot = "";
|
projectRoot = "";
|
||||||
targets = (
|
targets = (
|
||||||
97C146ED1CF9000F007C117D /* Runner */,
|
97C146ED1CF9000F007C117D /* Runner */,
|
||||||
|
4D0C7950292C15240064EE78 /* receive_sharing_intent */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
4D0C794F292C15240064EE78 /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
4D0C7957292C15240064EE78 /* MainInterface.storyboard in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EC1CF9000F007C117D /* Resources */ = {
|
97C146EC1CF9000F007C117D /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -268,6 +350,14 @@
|
|||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
4D0C794D292C15240064EE78 /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
4D0C7954292C15240064EE78 /* ShareViewController.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
97C146EA1CF9000F007C117D /* Sources */ = {
|
97C146EA1CF9000F007C117D /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
@@ -279,7 +369,23 @@
|
|||||||
};
|
};
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXTargetDependency section */
|
||||||
|
4D0C795A292C15240064EE78 /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 4D0C7950292C15240064EE78 /* receive_sharing_intent */;
|
||||||
|
targetProxy = 4D0C7959292C15240064EE78 /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
|
/* End PBXTargetDependency section */
|
||||||
|
|
||||||
/* Begin PBXVariantGroup section */
|
/* Begin PBXVariantGroup section */
|
||||||
|
4D0C7955292C15240064EE78 /* MainInterface.storyboard */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
4D0C7956292C15240064EE78 /* Base */,
|
||||||
|
);
|
||||||
|
name = MainInterface.storyboard;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
|
||||||
isa = PBXVariantGroup;
|
isa = PBXVariantGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -353,16 +459,19 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterPaperlessNgScanAndShare;
|
PRODUCT_BUNDLE_IDENTIFIER = "de.astubenbord.paperless-mobile";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -370,6 +479,114 @@
|
|||||||
};
|
};
|
||||||
name = Profile;
|
name = Profile;
|
||||||
};
|
};
|
||||||
|
4D0C795D292C15250064EE78 /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = receive_sharing_intent/receive_sharing_intent.entitlements;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = receive_sharing_intent/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = receive_sharing_intent;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "de.astubenbord.paperless-mobile.receive-sharing-intent";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
4D0C795E292C15250064EE78 /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = receive_sharing_intent/receive_sharing_intent.entitlements;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = receive_sharing_intent/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = receive_sharing_intent;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "de.astubenbord.paperless-mobile.receive-sharing-intent";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
4D0C795F292C15250064EE78 /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CLANG_ENABLE_OBJC_WEAK = YES;
|
||||||
|
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||||
|
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
|
||||||
|
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = receive_sharing_intent/receive_sharing_intent.entitlements;
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = receive_sharing_intent/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = receive_sharing_intent;
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
MTL_FAST_MATH = YES;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = "de.astubenbord.paperless-mobile.receive-sharing-intent";
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
97C147031CF9000F007C117D /* Debug */ = {
|
97C147031CF9000F007C117D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
@@ -481,16 +698,19 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterPaperlessNgScanAndShare;
|
PRODUCT_BUNDLE_IDENTIFIER = "de.astubenbord.paperless-mobile";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||||
@@ -503,16 +723,19 @@
|
|||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||||
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterPaperlessNgScanAndShare;
|
PRODUCT_BUNDLE_IDENTIFIER = "de.astubenbord.paperless-mobile";
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
@@ -523,6 +746,16 @@
|
|||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
4D0C7960292C15250064EE78 /* Build configuration list for PBXNativeTarget "receive_sharing_intent" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
4D0C795D292C15250064EE78 /* Debug */,
|
||||||
|
4D0C795E292C15250064EE78 /* Release */,
|
||||||
|
4D0C795F292C15250064EE78 /* Profile */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
|||||||
@@ -2,6 +2,22 @@
|
|||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>CFBundleURLTypes</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleTypeRole</key>
|
||||||
|
<string>Editor</string>
|
||||||
|
<key>CFBundleURLSchemes</key>
|
||||||
|
<array>
|
||||||
|
<string>ShareMedia</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
<dict/>
|
||||||
|
</array>
|
||||||
|
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>To upload photos, please allow permission to access your photo library.</string>
|
||||||
|
|
||||||
<key>NSFaceIDUsageDescription</key>
|
<key>NSFaceIDUsageDescription</key>
|
||||||
<string>Why is my app authenticating using face id?</string>
|
<string>Why is my app authenticating using face id?</string>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
@@ -48,6 +64,6 @@
|
|||||||
<key>UIStatusBarHidden</key>
|
<key>UIStatusBarHidden</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
10
ios/Runner/Runner.entitlements
Normal file
10
ios/Runner/Runner.entitlements
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?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">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>group.de.astubenbord.paperless-mobile</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="j1y-V4-xli">
|
||||||
|
<dependencies>
|
||||||
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
|
||||||
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
</dependencies>
|
||||||
|
<scenes>
|
||||||
|
<!--Share View Controller-->
|
||||||
|
<scene sceneID="ceB-am-kn3">
|
||||||
|
<objects>
|
||||||
|
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModuleProvider="target" sceneMemberID="viewController">
|
||||||
|
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||||
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
|
||||||
|
</view>
|
||||||
|
</viewController>
|
||||||
|
<placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
|
</objects>
|
||||||
|
</scene>
|
||||||
|
</scenes>
|
||||||
|
</document>
|
||||||
28
ios/receive_sharing_intent/Info.plist
Normal file
28
ios/receive_sharing_intent/Info.plist
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?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">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSExtension</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionAttributes</key>
|
||||||
|
<dict>
|
||||||
|
<key>PHSupportedMediaTypes</key>
|
||||||
|
<array>
|
||||||
|
<string>Image</string>
|
||||||
|
</array>
|
||||||
|
<key>NSExtensionActivationRule</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
<key>NSExtensionActivationSupportsFileWithMaxCount</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>NSExtensionMainStoryboard</key>
|
||||||
|
<string>MainInterface</string>
|
||||||
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
<string>com.apple.share-services</string>
|
||||||
|
</dict>
|
||||||
|
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
337
ios/receive_sharing_intent/ShareViewController.swift
Normal file
337
ios/receive_sharing_intent/ShareViewController.swift
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
import UIKit
|
||||||
|
import Social
|
||||||
|
import MobileCoreServices
|
||||||
|
import Photos
|
||||||
|
|
||||||
|
class ShareViewController: SLComposeServiceViewController {
|
||||||
|
let hostAppBundleIdentifier = "de.astubenbord.paperless-mobile"
|
||||||
|
let sharedKey = "ShareKey"
|
||||||
|
var sharedMedia: [SharedMediaFile] = []
|
||||||
|
var sharedText: [String] = []
|
||||||
|
let imageContentType = kUTTypeImage as String
|
||||||
|
let videoContentType = kUTTypeMovie as String
|
||||||
|
let textContentType = kUTTypeText as String
|
||||||
|
let urlContentType = kUTTypeURL as String
|
||||||
|
let fileURLType = kUTTypeFileURL as String;
|
||||||
|
|
||||||
|
override func isContentValid() -> Bool {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad();
|
||||||
|
}
|
||||||
|
|
||||||
|
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(fileURLType) {
|
||||||
|
handleFiles(content: content, attachment: attachment, index: index)
|
||||||
|
} else if attachment.hasItemConformingToTypeIdentifier(urlContentType) {
|
||||||
|
handleUrl(content: content, attachment: attachment, index: index)
|
||||||
|
} else if attachment.hasItemConformingToTypeIdentifier(videoContentType) {
|
||||||
|
handleVideos(content: content, attachment: attachment, index: index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func didSelectPost() {
|
||||||
|
// This is called after the user selects Post. Do the upload of contentText and/or NSExtensionContext attachments.
|
||||||
|
|
||||||
|
// Inform the host that we're done, so it un-blocks its UI. Note: Alternatively you could call super's -didSelectPost, which will similarly complete the extension context.
|
||||||
|
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
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: "group.\(this.hostAppBundleIdentifier)")
|
||||||
|
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: "group.\(this.hostAppBundleIdentifier)")
|
||||||
|
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: "group.\(this.hostAppBundleIdentifier)")!
|
||||||
|
.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: "group.\(this.hostAppBundleIdentifier)")
|
||||||
|
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: "group.\(this.hostAppBundleIdentifier)")!
|
||||||
|
.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: "group.\(this.hostAppBundleIdentifier)")
|
||||||
|
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: "group.\(this.hostAppBundleIdentifier)")!
|
||||||
|
.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: "group.\(this.hostAppBundleIdentifier)")
|
||||||
|
userDefaults?.set(this.toData(data: this.sharedMedia), forKey: this.sharedKey)
|
||||||
|
userDefaults?.synchronize()
|
||||||
|
this.redirectToHostApp(type: .file)
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
self?.dismissWithError()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func dismissWithError() {
|
||||||
|
print("[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) {
|
||||||
|
let url = URL(string: "ShareMedia://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) {
|
||||||
|
print("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: "group.\(hostAppBundleIdentifier)")!
|
||||||
|
.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() {
|
||||||
|
print("[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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<?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">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array>
|
||||||
|
<string>group.de.astubenbord.paperless-mobile</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -235,7 +235,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
|
|||||||
try {
|
try {
|
||||||
await BlocProvider.of<DocumentsCubit>(context).assignAsn(document);
|
await BlocProvider.of<DocumentsCubit>(context).assignAsn(document);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,7 +410,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
|
|||||||
await BlocProvider.of<DocumentsCubit>(context).removeDocument(document);
|
await BlocProvider.of<DocumentsCubit>(context).removeDocument(document);
|
||||||
showSnackBar(context, S.of(context).documentDeleteSuccessMessage);
|
showSnackBar(context, S.of(context).documentDeleteSuccessMessage);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
} finally {
|
} finally {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
await getIt<DocumentsCubit>().updateDocument(updatedDocument);
|
await getIt<DocumentsCubit>().updateDocument(updatedDocument);
|
||||||
showSnackBar(context, S.of(context).documentUpdateErrorMessage);
|
showSnackBar(context, S.of(context).documentUpdateErrorMessage);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
} finally {
|
} finally {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class _DocumentsPageState extends State<DocumentsPage> {
|
|||||||
try {
|
try {
|
||||||
BlocProvider.of<DocumentsCubit>(context).loadDocuments();
|
BlocProvider.of<DocumentsCubit>(context).loadDocuments();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +73,7 @@ class _DocumentsPageState extends State<DocumentsPage> {
|
|||||||
try {
|
try {
|
||||||
await documentsCubit.loadMore();
|
await documentsCubit.loadMore();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ class _DocumentsPageState extends State<DocumentsPage> {
|
|||||||
(filter) => filter.copyWith(page: 1),
|
(filter) => filter.copyWith(page: 1),
|
||||||
);
|
);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -476,7 +476,7 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
|
|||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context).unfocus();
|
||||||
widget.panelController.close();
|
widget.panelController.close();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ class _DocumentsPageAppBarState extends State<DocumentsPageAppBar> {
|
|||||||
S.of(context).documentsPageBulkDeleteSuccessfulText,
|
S.of(context).documentsPageBulkDeleteSuccessfulText,
|
||||||
);
|
);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class SavedViewSelectionWidget extends StatelessWidget {
|
|||||||
try {
|
try {
|
||||||
await BlocProvider.of<SavedViewCubit>(context).add(newView);
|
await BlocProvider.of<SavedViewCubit>(context).add(newView);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ class SavedViewSelectionWidget extends StatelessWidget {
|
|||||||
BlocProvider.of<SavedViewCubit>(context).selectView(null);
|
BlocProvider.of<SavedViewCubit>(context).selectView(null);
|
||||||
}
|
}
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ class SavedViewSelectionWidget extends StatelessWidget {
|
|||||||
try {
|
try {
|
||||||
BlocProvider.of<SavedViewCubit>(context).remove(view);
|
BlocProvider.of<SavedViewCubit>(context).remove(view);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class _HomePageState extends State<HomePage> {
|
|||||||
BlocProvider.of<StoragePathCubit>(context).initialize();
|
BlocProvider.of<StoragePathCubit>(context).initialize();
|
||||||
BlocProvider.of<SavedViewCubit>(context).initialize();
|
BlocProvider.of<SavedViewCubit>(context).initialize();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class BottomNavBar extends StatelessWidget {
|
|||||||
selectedIndex: selectedIndex,
|
selectedIndex: selectedIndex,
|
||||||
destinations: [
|
destinations: [
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
icon: const Icon(Icons.description),
|
icon: const Icon(Icons.description_outlined),
|
||||||
selectedIcon: Icon(
|
selectedIcon: Icon(
|
||||||
Icons.description,
|
Icons.description,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
@@ -27,7 +27,7 @@ class BottomNavBar extends StatelessWidget {
|
|||||||
label: S.of(context).bottomNavDocumentsPageLabel,
|
label: S.of(context).bottomNavDocumentsPageLabel,
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
icon: const Icon(Icons.document_scanner),
|
icon: const Icon(Icons.document_scanner_outlined),
|
||||||
selectedIcon: Icon(
|
selectedIcon: Icon(
|
||||||
Icons.document_scanner,
|
Icons.document_scanner,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
@@ -35,9 +35,7 @@ class BottomNavBar extends StatelessWidget {
|
|||||||
label: S.of(context).bottomNavScannerPageLabel,
|
label: S.of(context).bottomNavScannerPageLabel,
|
||||||
),
|
),
|
||||||
NavigationDestination(
|
NavigationDestination(
|
||||||
icon: const Icon(
|
icon: const Icon(Icons.sell_outlined),
|
||||||
Icons.sell,
|
|
||||||
),
|
|
||||||
selectedIcon: Icon(
|
selectedIcon: Icon(
|
||||||
Icons.sell,
|
Icons.sell,
|
||||||
color: Theme.of(context).colorScheme.primary,
|
color: Theme.of(context).colorScheme.primary,
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ class InfoDrawer extends StatelessWidget {
|
|||||||
getIt<TagCubit>().reset();
|
getIt<TagCubit>().reset();
|
||||||
getIt<DocumentScannerCubit>().reset();
|
getIt<DocumentScannerCubit>().reset();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class EditCorrespondentPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class CorrespondentWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
afterSelected?.call();
|
afterSelected?.call();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ class DocumentTypeWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
afterSelected?.call();
|
afterSelected?.call();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class EditStoragePathPage extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class StoragePathWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
afterSelected?.call();
|
afterSelected?.call();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class EditTagPage extends StatelessWidget {
|
|||||||
cubit.updateFilter(filter: updatedFilter);
|
cubit.updateFilter(filter: updatedFilter);
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ class TagWidget extends StatelessWidget {
|
|||||||
afterTagTapped!();
|
afterTagTapped!();
|
||||||
}
|
}
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ class _EditLabelPageState<T extends Label> extends State<EditLabelPage<T>> {
|
|||||||
} on PaperlessValidationErrors catch (errorMessages) {
|
} on PaperlessValidationErrors catch (errorMessages) {
|
||||||
setState(() => _errors = errorMessages);
|
setState(() => _errors = errorMessages);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,9 +98,11 @@ class _LoginPageState extends State<LoginPage> {
|
|||||||
form[ClientCertificateFormField.fkClientCertificate],
|
form[ClientCertificateFormField.fkClientCertificate],
|
||||||
);
|
);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
|
} on Map<String, dynamic> catch (error, stackTrace) {
|
||||||
|
showGenericError(context, error.values.first, stackTrace);
|
||||||
} catch (unknownError, stackTrace) {
|
} catch (unknownError, stackTrace) {
|
||||||
showError(context, ErrorMessage.unknown(), stackTrace);
|
showErrorMessage(context, ErrorMessage.unknown(), stackTrace);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() => _isLoginLoading = false);
|
setState(() => _isLoginLoading = false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,11 +30,16 @@ import 'package:intl/intl.dart';
|
|||||||
|
|
||||||
class DocumentUploadPage extends StatefulWidget {
|
class DocumentUploadPage extends StatefulWidget {
|
||||||
final Uint8List fileBytes;
|
final Uint8List fileBytes;
|
||||||
|
final String? title;
|
||||||
|
final String? filename;
|
||||||
final void Function()? afterUpload;
|
final void Function()? afterUpload;
|
||||||
|
|
||||||
const DocumentUploadPage({
|
const DocumentUploadPage({
|
||||||
Key? key,
|
Key? key,
|
||||||
required this.fileBytes,
|
required this.fileBytes,
|
||||||
this.afterUpload,
|
this.afterUpload,
|
||||||
|
this.title,
|
||||||
|
this.filename,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -42,18 +47,21 @@ class DocumentUploadPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
||||||
static const fkFileName = "fileName";
|
static const fkFileName = "filename";
|
||||||
|
|
||||||
static final fileNameDateFormat = DateFormat("yyyy_MM_ddTHH_mm_ss");
|
static final fileNameDateFormat = DateFormat("yyyy_MM_ddTHH_mm_ss");
|
||||||
|
|
||||||
final GlobalKey<FormBuilderState> _formKey = GlobalKey();
|
final GlobalKey<FormBuilderState> _formKey = GlobalKey();
|
||||||
|
|
||||||
PaperlessValidationErrors _errors = {};
|
PaperlessValidationErrors _errors = {};
|
||||||
bool _isUploadLoading = false;
|
bool _isUploadLoading = false;
|
||||||
|
late bool _syncTitleAndFilename;
|
||||||
|
final _now = DateTime.now();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
initializeDateFormatting(); //TODO: INTL (has to do with intl below)
|
_syncTitleAndFilename = widget.filename == null && widget.title == null;
|
||||||
|
initializeDateFormatting();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -83,7 +91,8 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
|||||||
FormBuilderTextField(
|
FormBuilderTextField(
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
name: DocumentModel.titleKey,
|
name: DocumentModel.titleKey,
|
||||||
initialValue: "scan_${fileNameDateFormat.format(DateTime.now())}",
|
initialValue:
|
||||||
|
widget.title ?? "scan_${fileNameDateFormat.format(_now)}",
|
||||||
validator: FormBuilderValidators.required(),
|
validator: FormBuilderValidators.required(),
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: S.of(context).documentTitlePropertyLabel,
|
labelText: S.of(context).documentTitlePropertyLabel,
|
||||||
@@ -92,29 +101,58 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
|||||||
onPressed: () {
|
onPressed: () {
|
||||||
_formKey.currentState?.fields[DocumentModel.titleKey]
|
_formKey.currentState?.fields[DocumentModel.titleKey]
|
||||||
?.didChange("");
|
?.didChange("");
|
||||||
_formKey.currentState?.fields[fkFileName]
|
if (_syncTitleAndFilename) {
|
||||||
?.didChange(".pdf");
|
_formKey.currentState?.fields[fkFileName]?.didChange("");
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
errorText: _errors[DocumentModel.titleKey],
|
errorText: _errors[DocumentModel.titleKey],
|
||||||
),
|
),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
final String? transformedValue =
|
final String transformedValue = _formatFilename(value ?? '');
|
||||||
value?.replaceAll(RegExp(r"[\W_]"), "_");
|
if (_syncTitleAndFilename) {
|
||||||
_formKey.currentState?.fields[fkFileName]
|
_formKey.currentState?.fields[fkFileName]
|
||||||
?.didChange("${transformedValue ?? ''}.pdf");
|
?.didChange(transformedValue);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
FormBuilderTextField(
|
FormBuilderTextField(
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
readOnly: true,
|
readOnly: _syncTitleAndFilename,
|
||||||
enabled: false,
|
enabled: !_syncTitleAndFilename,
|
||||||
name: fkFileName,
|
name: fkFileName,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: S.of(context).documentUploadFileNameLabel,
|
labelText: S.of(context).documentUploadFileNameLabel,
|
||||||
|
suffixText: ".pdf",
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
onPressed: () =>
|
||||||
|
_formKey.currentState?.fields[fkFileName]?.didChange(''),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
initialValue:
|
initialValue:
|
||||||
"scan_${fileNameDateFormat.format(DateTime.now())}.pdf",
|
widget.filename ?? "scan_${fileNameDateFormat.format(_now)}",
|
||||||
|
),
|
||||||
|
SwitchListTile(
|
||||||
|
value: _syncTitleAndFilename,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(
|
||||||
|
() => _syncTitleAndFilename = value,
|
||||||
|
);
|
||||||
|
if (_syncTitleAndFilename) {
|
||||||
|
final String transformedValue = _formatFilename(_formKey
|
||||||
|
.currentState
|
||||||
|
?.fields[DocumentModel.titleKey]
|
||||||
|
?.value as String);
|
||||||
|
if (_syncTitleAndFilename) {
|
||||||
|
_formKey.currentState?.fields[fkFileName]
|
||||||
|
?.didChange(transformedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
title: Text(S
|
||||||
|
.of(context)
|
||||||
|
.documentUploadPageSynchronizeTitleAndFilenameLabel), //TODO: INTL
|
||||||
),
|
),
|
||||||
FormBuilderDateTimePicker(
|
FormBuilderDateTimePicker(
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
@@ -202,7 +240,7 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
|||||||
fv[DocumentModel.correspondentKey] as IdQueryParameter;
|
fv[DocumentModel.correspondentKey] as IdQueryParameter;
|
||||||
await BlocProvider.of<DocumentsCubit>(context).addDocument(
|
await BlocProvider.of<DocumentsCubit>(context).addDocument(
|
||||||
widget.fileBytes,
|
widget.fileBytes,
|
||||||
_formKey.currentState?.value[fkFileName],
|
_padWithPdfExtension(_formKey.currentState?.value[fkFileName]),
|
||||||
onConsumptionFinished: _onConsumptionFinished,
|
onConsumptionFinished: _onConsumptionFinished,
|
||||||
title: title,
|
title: title,
|
||||||
documentType: docType.id,
|
documentType: docType.id,
|
||||||
@@ -215,11 +253,11 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
|||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
widget.afterUpload?.call();
|
widget.afterUpload?.call();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
} on PaperlessValidationErrors catch (errorMessages) {
|
} on PaperlessValidationErrors catch (errorMessages) {
|
||||||
setState(() => _errors = errorMessages);
|
setState(() => _errors = errorMessages);
|
||||||
} catch (unknownError, stackTrace) {
|
} catch (unknownError, stackTrace) {
|
||||||
showError(context, ErrorMessage.unknown(), stackTrace);
|
showErrorMessage(context, ErrorMessage.unknown(), stackTrace);
|
||||||
} finally {
|
} finally {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isUploadLoading = false;
|
_isUploadLoading = false;
|
||||||
@@ -228,6 +266,14 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _padWithPdfExtension(String source) {
|
||||||
|
return source.endsWith(".pdf") ? source : '$source.pdf';
|
||||||
|
}
|
||||||
|
|
||||||
|
String _formatFilename(String source) {
|
||||||
|
return source.replaceAll(RegExp(r"[\W_]"), "_");
|
||||||
|
}
|
||||||
|
|
||||||
void _onConsumptionFinished(document) {
|
void _onConsumptionFinished(document) {
|
||||||
ScaffoldMessenger.of(rootScaffoldKey.currentContext!).showSnackBar(
|
ScaffoldMessenger.of(rootScaffoldKey.currentContext!).showSnackBar(
|
||||||
SnackBar(
|
SnackBar(
|
||||||
@@ -236,7 +282,7 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
|
|||||||
try {
|
try {
|
||||||
getIt<DocumentsCubit>().reloadDocuments();
|
getIt<DocumentsCubit>().reloadDocuments();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
label:
|
label:
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ class _ScannerPageState extends State<ScannerPage>
|
|||||||
BlocProvider.of<DocumentScannerCubit>(context)
|
BlocProvider.of<DocumentScannerCubit>(context)
|
||||||
.removeScan(index);
|
.removeScan(index);
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
index: index,
|
index: index,
|
||||||
@@ -205,7 +205,7 @@ class _ScannerPageState extends State<ScannerPage>
|
|||||||
try {
|
try {
|
||||||
BlocProvider.of<DocumentScannerCubit>(context).reset();
|
BlocProvider.of<DocumentScannerCubit>(context).reset();
|
||||||
} on ErrorMessage catch (error, stackTrace) {
|
} on ErrorMessage catch (error, stackTrace) {
|
||||||
showError(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,10 +224,16 @@ class _ScannerPageState extends State<ScannerPage>
|
|||||||
);
|
);
|
||||||
if (result?.files.single.path != null) {
|
if (result?.files.single.path != null) {
|
||||||
File file = File(result!.files.single.path!);
|
File file = File(result!.files.single.path!);
|
||||||
if (!supportedFileExtensions.contains(file.path.split('.').last)) {
|
if (!supportedFileExtensions.contains(
|
||||||
//TODO: Show error message;
|
file.path.split('.').last.toLowerCase(),
|
||||||
|
)) {
|
||||||
|
showErrorMessage(
|
||||||
|
context,
|
||||||
|
const ErrorMessage(ErrorCode.unsupportedFileFormat),
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final filename = extractFilenameFromPath(file.path);
|
||||||
final mimeType = lookupMimeType(file.path) ?? '';
|
final mimeType = lookupMimeType(file.path) ?? '';
|
||||||
late Uint8List fileBytes;
|
late Uint8List fileBytes;
|
||||||
if (mimeType.startsWith('image')) {
|
if (mimeType.startsWith('image')) {
|
||||||
@@ -244,6 +250,7 @@ class _ScannerPageState extends State<ScannerPage>
|
|||||||
value: getIt<DocumentsCubit>(),
|
value: getIt<DocumentsCubit>(),
|
||||||
child: LabelBlocProvider(
|
child: LabelBlocProvider(
|
||||||
child: DocumentUploadPage(
|
child: DocumentUploadPage(
|
||||||
|
filename: filename,
|
||||||
fileBytes: fileBytes,
|
fileBytes: fileBytes,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"@@locale": "de",
|
"@@locale": "de",
|
||||||
"documentTitlePropertyLabel": "Titel",
|
"documentTitlePropertyLabel": "Titel",
|
||||||
"documentCreatedPropertyLabel": "Erstellt Am",
|
"documentCreatedPropertyLabel": "Ausgestellt am",
|
||||||
"documentAddedPropertyLabel": "Hinzugefügt Am",
|
"documentAddedPropertyLabel": "Hinzugefügt am",
|
||||||
"documentModifiedPropertyLabel": "Geändert Am",
|
"documentModifiedPropertyLabel": "Geändert am",
|
||||||
"documentDocumentTypePropertyLabel": "Dokumenttyp",
|
"documentDocumentTypePropertyLabel": "Dokumenttyp",
|
||||||
"documentCorrespondentPropertyLabel": "Korrespondent",
|
"documentCorrespondentPropertyLabel": "Korrespondent",
|
||||||
"documentStoragePathPropertyLabel": "Speicherpfad",
|
"documentStoragePathPropertyLabel": "Speicherpfad",
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
"documentScannerPageUploadFromThisDeviceButtonLabel": "Lade ein Dokument von diesem Gerät hoch",
|
"documentScannerPageUploadFromThisDeviceButtonLabel": "Lade ein Dokument von diesem Gerät hoch",
|
||||||
"addTagPageTitle": "Neuer Tag",
|
"addTagPageTitle": "Neuer Tag",
|
||||||
"addCorrespondentPageTitle": "Neuer Korrespondent",
|
"addCorrespondentPageTitle": "Neuer Korrespondent",
|
||||||
"addDocumentTypePageTitle": "Neuer Dokumententyp",
|
"addDocumentTypePageTitle": "Neuer Dokumenttyp",
|
||||||
"labelNamePropertyLabel": "Name",
|
"labelNamePropertyLabel": "Name",
|
||||||
"labelMatchPropertyLabel": "Zuweisungsmuster",
|
"labelMatchPropertyLabel": "Zuweisungsmuster",
|
||||||
"labelMatchingAlgorithmPropertyLabel": "Zuweisungsalgorithmus",
|
"labelMatchingAlgorithmPropertyLabel": "Zuweisungsalgorithmus",
|
||||||
@@ -195,5 +195,6 @@
|
|||||||
"appDrawerHeaderLoggedInAsText": "Eingeloggt als ",
|
"appDrawerHeaderLoggedInAsText": "Eingeloggt als ",
|
||||||
"labelAnyAssignedText": "Beliebig zugewiesen",
|
"labelAnyAssignedText": "Beliebig zugewiesen",
|
||||||
"deleteViewDialogContentText": "Möchtest Du diese Ansicht wirklich löschen?",
|
"deleteViewDialogContentText": "Möchtest Du diese Ansicht wirklich löschen?",
|
||||||
"deleteViewDialogTitleText": "Lösche Ansicht "
|
"deleteViewDialogTitleText": "Lösche Ansicht ",
|
||||||
|
"documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronisiere Titel und Dateiname"
|
||||||
}
|
}
|
||||||
@@ -196,5 +196,6 @@
|
|||||||
"appDrawerHeaderLoggedInAsText": "Logged in as ",
|
"appDrawerHeaderLoggedInAsText": "Logged in as ",
|
||||||
"labelAnyAssignedText": "Any assigned",
|
"labelAnyAssignedText": "Any assigned",
|
||||||
"deleteViewDialogContentText": "Do you really want to delete this view?",
|
"deleteViewDialogContentText": "Do you really want to delete this view?",
|
||||||
"deleteViewDialogTitleText": "Delete view "
|
"deleteViewDialogTitleText": "Delete view ",
|
||||||
|
"documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronize title and filename"
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
import 'package:flutter_native_splash/flutter_native_splash.dart';
|
||||||
|
import 'package:fluttertoast/fluttertoast.dart';
|
||||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:intl/intl_standalone.dart';
|
import 'package:intl/intl_standalone.dart';
|
||||||
@@ -15,6 +16,7 @@ import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.da
|
|||||||
import 'package:paperless_mobile/core/global/asset_images.dart';
|
import 'package:paperless_mobile/core/global/asset_images.dart';
|
||||||
import 'package:paperless_mobile/core/global/constants.dart';
|
import 'package:paperless_mobile/core/global/constants.dart';
|
||||||
import 'package:paperless_mobile/core/global/http_self_signed_certificate_override.dart';
|
import 'package:paperless_mobile/core/global/http_self_signed_certificate_override.dart';
|
||||||
|
import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart';
|
||||||
import 'package:paperless_mobile/core/model/error_message.dart';
|
import 'package:paperless_mobile/core/model/error_message.dart';
|
||||||
import 'package:paperless_mobile/core/service/file_service.dart';
|
import 'package:paperless_mobile/core/service/file_service.dart';
|
||||||
import 'package:paperless_mobile/di_initializer.dart';
|
import 'package:paperless_mobile/di_initializer.dart';
|
||||||
@@ -132,21 +134,40 @@ class AuthenticationWrapper extends StatefulWidget {
|
|||||||
|
|
||||||
class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
||||||
bool isFileTypeSupported(SharedMediaFile file) {
|
bool isFileTypeSupported(SharedMediaFile file) {
|
||||||
return supportedFileExtensions.contains(file.path.split('.').last);
|
return supportedFileExtensions.contains(
|
||||||
|
file.path.split('.').last.toLowerCase(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleReceivedFiles(List<SharedMediaFile> files) async {
|
void handleReceivedFiles(List<SharedMediaFile> files) async {
|
||||||
if (files.isEmpty) {
|
if (files.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!isFileTypeSupported(files.first)) {
|
late final SharedMediaFile file;
|
||||||
showError(context, const ErrorMessage(ErrorCode.unsupportedFileFormat));
|
if (Platform.isIOS) {
|
||||||
await Future.delayed(
|
// Workaround: https://stackoverflow.com/a/72813212
|
||||||
const Duration(seconds: 2),
|
file = SharedMediaFile(
|
||||||
() => SystemNavigator.pop(),
|
files.first.path.replaceAll('file://', ''),
|
||||||
|
files.first.thumbnail,
|
||||||
|
files.first.duration,
|
||||||
|
files.first.type,
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
file = files.first;
|
||||||
}
|
}
|
||||||
final bytes = File(files.first.path).readAsBytesSync();
|
|
||||||
|
if (!isFileTypeSupported(file)) {
|
||||||
|
Fluttertoast.showToast(
|
||||||
|
msg: translateError(context, ErrorCode.unsupportedFileFormat),
|
||||||
|
);
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
// As stated in the docs, SystemNavigator.pop() is ignored on IOS to comply with HCI guidelines.
|
||||||
|
await SystemNavigator.pop();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final filename = extractFilenameFromPath(file.path);
|
||||||
|
final bytes = File(file.path).readAsBytesSync();
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
@@ -156,6 +177,7 @@ class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
|||||||
child: DocumentUploadPage(
|
child: DocumentUploadPage(
|
||||||
fileBytes: bytes,
|
fileBytes: bytes,
|
||||||
afterUpload: () => SystemNavigator.pop(),
|
afterUpload: () => SystemNavigator.pop(),
|
||||||
|
filename: filename,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -184,7 +206,7 @@ class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
top: true,
|
top: false,
|
||||||
left: false,
|
left: false,
|
||||||
right: false,
|
right: false,
|
||||||
bottom: false,
|
bottom: false,
|
||||||
|
|||||||
@@ -34,7 +34,32 @@ void showSnackBar(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void showError(
|
void showGenericError(
|
||||||
|
BuildContext context,
|
||||||
|
dynamic error, [
|
||||||
|
StackTrace? stackTrace,
|
||||||
|
]) {
|
||||||
|
showSnackBar(
|
||||||
|
context,
|
||||||
|
error.toString(),
|
||||||
|
action: SnackBarAction(
|
||||||
|
label: S.of(context).errorReportLabel,
|
||||||
|
textColor: Colors.amber,
|
||||||
|
onPressed: () => GithubIssueService.createIssueFromError(
|
||||||
|
context,
|
||||||
|
stackTrace: stackTrace,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
log(
|
||||||
|
"An error has occurred.",
|
||||||
|
error: error,
|
||||||
|
stackTrace: stackTrace,
|
||||||
|
time: DateTime.now(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showErrorMessage(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
ErrorMessage error, [
|
ErrorMessage error, [
|
||||||
StackTrace? stackTrace,
|
StackTrace? stackTrace,
|
||||||
@@ -91,3 +116,7 @@ String formatLocalDate(BuildContext context, DateTime dateTime) {
|
|||||||
final tag = Localizations.maybeLocaleOf(context)?.toLanguageTag();
|
final tag = Localizations.maybeLocaleOf(context)?.toLanguageTag();
|
||||||
return DateFormat.yMMMd(tag).format(dateTime);
|
return DateFormat.yMMMd(tag).format(dateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String extractFilenameFromPath(String path) {
|
||||||
|
return path.split(RegExp('[./]')).reversed.skip(1).first;
|
||||||
|
}
|
||||||
|
|||||||
@@ -588,6 +588,13 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
fluttertoast:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: fluttertoast
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "8.1.1"
|
||||||
font_awesome_flutter:
|
font_awesome_flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ dependencies:
|
|||||||
receive_sharing_intent: ^1.4.5
|
receive_sharing_intent: ^1.4.5
|
||||||
uuid: ^3.0.6
|
uuid: ^3.0.6
|
||||||
flutter_typeahead: ^4.1.1
|
flutter_typeahead: ^4.1.1
|
||||||
|
fluttertoast: ^8.1.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
integration_test:
|
integration_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user