Refactor QR scan and share and add QRS support
This commit is contained in:
@@ -27,36 +27,42 @@
|
||||
#if os(iOS)
|
||||
private var iOSBody: some View {
|
||||
NavigationStackCompat {
|
||||
QRScannerControllerView(controller: controller)
|
||||
.ignoresSafeArea()
|
||||
.navigationTitle("Scan QR Code")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button("Cancel") { dismiss() }
|
||||
}
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
Menu {
|
||||
if controller.availableCameras.count > 1 {
|
||||
Menu("Camera") {
|
||||
ForEach(controller.availableCameras, id: \.uniqueID) { camera in
|
||||
Button {
|
||||
controller.selectCamera(camera)
|
||||
} label: {
|
||||
if camera.uniqueID == controller.selectedCamera?.uniqueID {
|
||||
Label(camera.localizedName, systemImage: "checkmark")
|
||||
} else {
|
||||
Text(camera.localizedName)
|
||||
}
|
||||
ZStack {
|
||||
QRScannerControllerView(controller: controller)
|
||||
.ignoresSafeArea()
|
||||
|
||||
if controller.qrsMode {
|
||||
qrsProgressOverlay
|
||||
}
|
||||
}
|
||||
.navigationTitle("Scan QR Code")
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button("Cancel") { dismiss() }
|
||||
}
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
Menu {
|
||||
if controller.availableCameras.count > 1 {
|
||||
Menu("Camera") {
|
||||
ForEach(controller.availableCameras, id: \.uniqueID) { camera in
|
||||
Button {
|
||||
controller.selectCamera(camera)
|
||||
} label: {
|
||||
if camera.uniqueID == controller.selectedCamera?.uniqueID {
|
||||
Label(camera.localizedName, systemImage: "checkmark")
|
||||
} else {
|
||||
Text(camera.localizedName)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
}
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.alert($alert)
|
||||
.onAppear {
|
||||
@@ -68,8 +74,14 @@
|
||||
#if os(macOS)
|
||||
private var macOSBody: some View {
|
||||
VStack(spacing: 0) {
|
||||
QRScannerControllerView(controller: controller)
|
||||
.frame(minWidth: 400, minHeight: 300)
|
||||
ZStack {
|
||||
QRScannerControllerView(controller: controller)
|
||||
|
||||
if controller.qrsMode {
|
||||
qrsProgressOverlay
|
||||
}
|
||||
}
|
||||
.frame(minWidth: 400, minHeight: 300)
|
||||
|
||||
Divider()
|
||||
|
||||
@@ -102,11 +114,29 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
private var qrsProgressOverlay: some View {
|
||||
ZStack {
|
||||
Color.black.opacity(0.5)
|
||||
.ignoresSafeArea()
|
||||
|
||||
let k = controller.decoder?.k ?? 0
|
||||
let framesScanned = controller.framesScanned
|
||||
let scanProgress = k > 0 ? min(1.0, Double(framesScanned) / Double(k) / 1.2) : 0
|
||||
|
||||
CircularProgressView(
|
||||
progress: scanProgress,
|
||||
total: k
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private func handleScanResult(_ result: Result<QRScanResult, QRScanError>) {
|
||||
switch result {
|
||||
case let .success(scanResult):
|
||||
dismiss()
|
||||
onScan(scanResult)
|
||||
Task { @MainActor in
|
||||
onScan(scanResult)
|
||||
}
|
||||
case let .failure(error):
|
||||
switch error {
|
||||
case .permissionDenied:
|
||||
@@ -124,4 +154,38 @@
|
||||
}
|
||||
}
|
||||
|
||||
private struct CircularProgressView: View {
|
||||
let progress: Double
|
||||
let total: Int
|
||||
|
||||
private let size: CGFloat = 96
|
||||
private let lineWidth: CGFloat = 8
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
Circle()
|
||||
.stroke(Color.white.opacity(0.3), lineWidth: lineWidth)
|
||||
.frame(width: size, height: size)
|
||||
|
||||
Circle()
|
||||
.trim(from: 0, to: progress)
|
||||
.stroke(Color.white, style: StrokeStyle(lineWidth: lineWidth, lineCap: .round))
|
||||
.frame(width: size, height: size)
|
||||
.rotationEffect(.degrees(-90))
|
||||
.animation(.easeInOut(duration: 0.2), value: progress)
|
||||
|
||||
if total > 0 {
|
||||
Text("\(min(99, Int(progress * 100)))%")
|
||||
.font(.system(size: 20, weight: .semibold))
|
||||
.foregroundStyle(.white)
|
||||
}
|
||||
|
||||
Text("QRS")
|
||||
.font(.system(size: 32, weight: .bold))
|
||||
.foregroundStyle(.white)
|
||||
.offset(y: -size / 2 - 40)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user