mirror of
https://github.com/sudosylabs/vnidrop.git
synced 2026-08-05 02:29:55 +02:00
feat(receive): add adaptive receive flow and document opening
This commit is contained in:
@@ -58,16 +58,68 @@ final class VniDropHostViewController: UIViewController {
|
||||
}
|
||||
|
||||
struct ComposeView: UIViewControllerRepresentable {
|
||||
let externalInvitations: ExternalInvitationController
|
||||
|
||||
func makeUIViewController(context: Self.Context) -> UIViewController {
|
||||
VniDropHostViewController(composeController: MainViewControllerKt.MainViewController())
|
||||
VniDropHostViewController(
|
||||
composeController: MainViewControllerKt.MainViewController(
|
||||
externalInvitations: externalInvitations
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
func updateUIViewController(_ uiViewController: UIViewController, context: Self.Context) {}
|
||||
}
|
||||
|
||||
struct ContentView: View {
|
||||
let externalInvitations: ExternalInvitationController
|
||||
|
||||
var body: some View {
|
||||
ComposeView()
|
||||
ComposeView(externalInvitations: externalInvitations)
|
||||
.ignoresSafeArea()
|
||||
.onOpenURL(perform: openInvitation)
|
||||
}
|
||||
|
||||
private func openInvitation(_ url: URL) {
|
||||
guard url.pathExtension.caseInsensitiveCompare("vnd") == .orderedSame else {
|
||||
externalInvitations.reportOpenFailure(message: "This is not a VniDrop invitation")
|
||||
return
|
||||
}
|
||||
|
||||
let hasSecurityAccess = url.startAccessingSecurityScopedResource()
|
||||
defer {
|
||||
if hasSecurityAccess {
|
||||
url.stopAccessingSecurityScopedResource()
|
||||
}
|
||||
}
|
||||
|
||||
do {
|
||||
let values = try url.resourceValues(forKeys: [.fileSizeKey])
|
||||
if let fileSize = values.fileSize, fileSize > 65_536 {
|
||||
throw InvitationOpenError.tooLarge
|
||||
}
|
||||
let data = try Data(contentsOf: url, options: .mappedIfSafe)
|
||||
guard data.count <= 65_536 else { throw InvitationOpenError.tooLarge }
|
||||
guard let raw = String(data: data, encoding: .utf8) else {
|
||||
throw InvitationOpenError.invalidEncoding
|
||||
}
|
||||
externalInvitations.openInvitation(raw: raw)
|
||||
} catch {
|
||||
externalInvitations.reportOpenFailure(
|
||||
message: (error as? LocalizedError)?.errorDescription ?? "The invitation could not be opened"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum InvitationOpenError: LocalizedError {
|
||||
case tooLarge
|
||||
case invalidEncoding
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .tooLarge: "The invitation is too large"
|
||||
case .invalidEncoding: "The invitation is not valid text"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,45 @@
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDocumentTypes</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>VniDrop Invitation</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
<key>LSHandlerRank</key>
|
||||
<string>Owner</string>
|
||||
<key>LSItemContentTypes</key>
|
||||
<array>
|
||||
<string>com.vnidrop.app.invitation</string>
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UTExportedTypeDeclarations</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>UTTypeConformsTo</key>
|
||||
<array>
|
||||
<string>public.data</string>
|
||||
</array>
|
||||
<key>UTTypeDescription</key>
|
||||
<string>VniDrop Invitation</string>
|
||||
<key>UTTypeIdentifier</key>
|
||||
<string>com.vnidrop.app.invitation</string>
|
||||
<key>UTTypeTagSpecification</key>
|
||||
<dict>
|
||||
<key>public.filename-extension</key>
|
||||
<array>
|
||||
<string>vnd</string>
|
||||
</array>
|
||||
<key>public.mime-type</key>
|
||||
<string>application/vnd.vnidrop.transfer</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</array>
|
||||
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||
<true/>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<true/>
|
||||
</dict>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import Shared
|
||||
import SwiftUI
|
||||
|
||||
@main
|
||||
struct iOSApp: App {
|
||||
private let externalInvitations = ExternalInvitationController()
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
ContentView()
|
||||
ContentView(externalInvitations: externalInvitations)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user