Add QR scanner support for macOS with camera selection

- Refactor QR scanner into separate Scanner module for iOS and macOS
- Add camera selection menu for devices with multiple cameras
- Use Vision framework for QR detection on macOS
- Remove tvOS QR scanner support (continuity camera)
- Add camera entitlement and usage description for macOS
- Fix minor issues in Intents and ExtensionProvider
This commit is contained in:
世界
2026-01-01 18:18:03 +08:00
parent 251a79f5d7
commit e2c378d42b
15 changed files with 687 additions and 108 deletions
@@ -9,14 +9,15 @@ public struct NewProfileMenuView: View {
@EnvironmentObject private var environments: ExtensionEnvironments
@Environment(\.dismiss) private var dismiss
@State private var alert: AlertState?
@State private var showFileImporter = false
@State private var importRequest: NewProfileView.ImportRequest?
@State private var localImportRequest: NewProfileView.LocalImportRequest?
#if os(iOS)
@State private var showQRScanner = false
#elseif os(tvOS)
#if os(tvOS)
@State private var importCompleted = false
#elseif os(macOS)
#else
@State private var showFileImporter = false
@State private var showQRScanner = false
#endif
#if os(macOS)
@State private var showNewProfile = false
#endif
@@ -76,6 +77,19 @@ public struct NewProfileMenuView: View {
})
.environmentObject(environments)
}
.sheet(isPresented: $showQRScanner) {
QRScannerView { result in
handleQRScanResult(result)
}
.frame(minWidth: 500, minHeight: 400)
}
.sheet(item: $importRequest) { request in
NewProfileView(request, onSuccess: { profile in
await SharedPreferences.selectedProfileID.set(profile.mustID)
dismiss()
})
.environmentObject(environments)
}
}
#endif
@@ -117,10 +131,10 @@ public struct NewProfileMenuView: View {
handleFileImport(result)
}
#endif
#if os(iOS)
#if !os(tvOS)
.sheet(isPresented: $showQRScanner) {
QRCodeScannerView { remoteProfile in
importRequest = NewProfileView.ImportRequest(name: remoteProfile.name, url: remoteProfile.url)
QRScannerView { result in
handleQRScanResult(result)
}
}
#endif
@@ -148,7 +162,7 @@ public struct NewProfileMenuView: View {
}
#endif
#if os(iOS)
#if !os(tvOS)
FormButton {
showQRScanner = true
} label: {
@@ -214,4 +228,26 @@ public struct NewProfileMenuView: View {
}
}
#endif
#if !os(tvOS)
private func handleQRScanResult(_ result: QRScanResult) {
var error: NSError?
let remoteProfile = LibboxParseRemoteProfileImportLink(result.string, &error)
if let error {
alert = AlertState(
title: String(localized: "Invalid QR Code"),
message: error.localizedDescription
)
return
}
guard let remoteProfile else {
alert = AlertState(
title: String(localized: "Invalid QR Code"),
message: String(localized: "The QR code does not contain a valid profile import link.")
)
return
}
importRequest = NewProfileView.ImportRequest(name: remoteProfile.name, url: remoteProfile.url)
}
#endif
}