Show file name for iOS share extension

This commit is contained in:
Leon Böttger committed 2025-08-17 21:44:28 +02:00
1 parent e808b71446
commit 006f389891
8 files changed
+198 -39

No files matched your search

@@ -15,8 +15,9 @@ import Network
import System
import SwiftECC
import CryptoKit
import SwiftUI
public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearbyConnectionDelegate, OutboundNearbyConnectionDelegate {
public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearbyConnectionDelegate, OutboundNearbyConnectionDelegate, ObservableObject {
#if !EXTENSION
private let sleepManager = SleepManager.shared
@@ -39,6 +40,8 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
public var mainAppDelegate: (any InboundAppDelegate)?
public static let shared = NearbyConnectionManager()
@Published var attachments: AttachmentDetails? = nil
override init() {
#if os(macOS)
+15
View File
@@ -83,6 +83,7 @@
EB704A832E4B10D4008E608F /* DistributionDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB704A812E4A7BAE008E608F /* DistributionDetector.swift */; };
EB704A842E4B10D4008E608F /* DistributionDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB704A812E4A7BAE008E608F /* DistributionDetector.swift */; };
EB7654782E525ACC006B4AA3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = EB7654772E525ACC006B4AA3 /* MainMenu.xib */; };
EB76547D2E526164006B4AA3 /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = EB76547C2E526164006B4AA3 /* ZIPFoundation */; };
EB7CD1452D6FB0C300CB0CB5 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7CD1442D6FB0C100CB0CB5 /* Logger.swift */; };
EB7CD1462D6FB0E800CB0CB5 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7CD1442D6FB0C100CB0CB5 /* Logger.swift */; };
EB7F54122D78E96000989564 /* TutorialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7F54112D78E95C00989564 /* TutorialView.swift */; };
@@ -346,6 +347,7 @@
EB5C37D82E377ACF0052EFD7 /* SwiftECC in Frameworks */,
EB5C37D62E377ACF0052EFD7 /* SwiftProtobuf in Frameworks */,
EB9925852E45EF0900357055 /* QRCode in Frameworks */,
EB76547D2E526164006B4AA3 /* ZIPFoundation in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1528,6 +1530,14 @@
minimumVersion = 2.1.0;
};
};
EB7654792E526155006B4AA3 /* XCRemoteSwiftPackageReference "ZIPFoundation" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/weichsel/ZIPFoundation.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 0.9.19;
};
};
EB886E562E4E66420052B7D9 /* XCRemoteSwiftPackageReference "LUI" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/leonboe1/LUI.git";
@@ -1590,6 +1600,11 @@
package = 69DA9A3429E1994C00A442DA /* XCRemoteSwiftPackageReference "SwiftECC" */;
productName = SwiftECC;
};
EB76547C2E526164006B4AA3 /* ZIPFoundation */ = {
isa = XCSwiftPackageProductDependency;
package = EB7654792E526155006B4AA3 /* XCRemoteSwiftPackageReference "ZIPFoundation" */;
productName = ZIPFoundation;
};
EB886E572E4E66420052B7D9 /* LUI */ = {
isa = XCSwiftPackageProductDependency;
package = EB886E562E4E66420052B7D9 /* XCRemoteSwiftPackageReference "LUI" */;
@@ -1,5 +1,5 @@
{
"originHash" : "6596056df2297c97fbb8a90f8b23b4feec22b8d0fbdb59f154e1c543f10c631c",
"originHash" : "212cf044c2b0bab89578ca93a3666a656e0c44fb54a69f813c4cc4fae07827d7",
"pins" : [
{
"identity" : "applewatchscreensize",
+107
View File
@@ -10585,6 +10585,113 @@
}
}
},
"YouAreSending" : {
"extractionState" : "manual",
"localizations" : {
"ar" : {
"stringUnit" : {
"state" : "translated",
"value" : "أنت ترسل"
}
},
"de" : {
"stringUnit" : {
"state" : "translated",
"value" : "Du sendest"
}
},
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "You’re sending"
}
},
"es" : {
"stringUnit" : {
"state" : "translated",
"value" : "Estás enviando"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Vous envoyez"
}
},
"hu" : {
"stringUnit" : {
"state" : "translated",
"value" : "Küldés alatt"
}
},
"it" : {
"stringUnit" : {
"state" : "translated",
"value" : "Stai inviando"
}
},
"ja" : {
"stringUnit" : {
"state" : "translated",
"value" : "送信中です"
}
},
"ko" : {
"stringUnit" : {
"state" : "translated",
"value" : "보내는 중입니다"
}
},
"nl" : {
"stringUnit" : {
"state" : "translated",
"value" : "Je bent aan het verzenden"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "translated",
"value" : "Você está enviando"
}
},
"pt-PT" : {
"stringUnit" : {
"state" : "translated",
"value" : "Está a enviar"
}
},
"ro" : {
"stringUnit" : {
"state" : "translated",
"value" : "Trimiteți"
}
},
"ru" : {
"stringUnit" : {
"state" : "translated",
"value" : "Вы отправляете"
}
},
"th" : {
"stringUnit" : {
"state" : "translated",
"value" : "คุณกำลังส่ง"
}
},
"uk" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ви надсилаєте"
}
},
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "您正在发送"
}
}
}
},
"YouAreVisibleAs" : {
"extractionState" : "manual",
"localizations" : {
+25 -15
View File
@@ -10,11 +10,9 @@ import LUI
struct ContentView: View {
var attachments: AttachmentDetails? = nil
var body: some View {
AppRootView(isPlus: .constant(true), phoneView: {
DeviceListView(attachments: attachments)
DeviceListView()
}, settingsView: {
EmptyView()
})
@@ -23,29 +21,41 @@ struct ContentView: View {
struct DeviceListView: View {
var attachments: AttachmentDetails? = nil
@StateObject var sendModel = SendModel()
#if !EXTENSION
@StateObject var receiveModel = ReceiveModel()
#endif
@ObservedObject var nearbyConnectionManager = NearbyConnectionManager.shared
var body: some View {
NavigationSubView(header: "QuickDrop ") {
// "You're visible as"
VStack(alignment: .leading, spacing: 8) {
FooterView(text: "YouAreVisibleAs")
Text(NearbyConnectionManager.shared.deviceInfo.name ?? "Unknown".localized())
.fontWeight(.bold)
.padding(.horizontal, 16)
.padding(.vertical, 6)
.background(Color.defaultForegroundColor)
.cornerRadius(24)
.padding(.horizontal)
let attachments = nearbyConnectionManager.attachments
FooterView(text: attachments == nil ? "YouAreVisibleAs".localized() : "YouAreSending".localized())
HStack {
if let image = attachments?.previewImage {
image
.resizable()
.scaledToFill()
.frame(width: 10, height: 10)
}
Text(attachments?.shortDescription ?? NearbyConnectionManager.shared.deviceInfo.name ?? "Unknown".localized())
.fontWeight(.bold)
}
.padding(.horizontal, 16)
.padding(.vertical, 6)
.background(Color.defaultForegroundColor)
.cornerRadius(24)
.padding(.horizontal)
}
.padding(.top, 8)
.frame(maxWidth: .infinity, alignment: .leading)
@@ -72,7 +82,7 @@ struct DeviceListView: View {
let isSelected = sendModel.selectedDevice == device
ZStack {
if let attachments = attachments {
if let attachments = NearbyConnectionManager.shared.attachments {
LUIButton {
sendModel.urls = attachments.urls
sendModel.textToSend = attachments.textToSend
+9 -3
View File
@@ -138,10 +138,19 @@ class ReceiveModel: ObservableObject, InboundAppDelegate {
func finish() {
if let error = error {
#if os(iOS)
errorVibration()
#endif
controlPlusScreen(false)
ErrorAlertHandler.shared.showErrorAlert(for: device.name ?? "Android", error: error)
} else {
#if os(iOS)
doubleVibration()
#endif
if wasPlainTextTransfer {
showCopiedToClipboardAlert()
}
@@ -165,9 +174,6 @@ class ReceiveModel: ObservableObject, InboundAppDelegate {
DispatchQueue.main.async {
BezelNotification.show(messageText: "InsertedIntoClipboard".localized(), icon: .clipboard)
}
#else
// iOS
doubleVibration()
#endif
}
+14
View File
@@ -6,6 +6,9 @@
//
import SwiftUI
#if os(iOS)
import LUI
#endif
class SendModel: ObservableObject, OutboundAppDelegate {
@@ -47,6 +50,10 @@ class SendModel: ObservableObject, OutboundAppDelegate {
func connectionFailed(with error: any Error) {
#if os(iOS)
errorVibration()
#endif
ErrorAlertHandler.shared.showErrorAlert(for: selectedDevice?.name ?? "?", error: error)
progressValue = nil
@@ -62,9 +69,16 @@ class SendModel: ObservableObject, OutboundAppDelegate {
}
func transferFinished() {
#if os(iOS)
doubleVibration()
#endif
progressValue = 0
selectedDevice = nil
progressState = "TransferFinished".localized()
NearbyConnectionManager.shared.attachments?.closeView?()
}
func startTransferWithQrCode(device: RemoteDeviceInfo) {
+23 -19
View File
@@ -22,26 +22,30 @@ class ShareViewController: UIViewController {
self?.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil)
}
// Replace with your app’s SwiftUI entry view
let contentView = ContentView(attachments: attachmentDetails)
// Embed SwiftUI inside the extension’s controller
let hostingController = UIHostingController(rootView: contentView)
addChild(hostingController)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(hostingController.view)
// Pin to edges
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(equalTo: view.topAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
hostingController.didMove(toParent: self)
DispatchQueue.main.async {
NearbyConnectionManager.shared.attachments = attachmentDetails
}
})
// Replace with your app’s SwiftUI entry view
let contentView = ContentView()
// Embed SwiftUI inside the extension’s controller
let hostingController = UIHostingController(rootView: contentView)
addChild(hostingController)
hostingController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(hostingController.view)
// Pin to edges
NSLayoutConstraint.activate([
hostingController.view.topAnchor.constraint(equalTo: view.topAnchor),
hostingController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
hostingController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
hostingController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
hostingController.didMove(toParent: self)
}
}