119 lines
3.5 KiB
Swift
119 lines
3.5 KiB
Swift
//
|
|
// MainView.swift
|
|
// JustScanIt
|
|
//
|
|
// Created by Pradyun Setti on 03/07/2024.
|
|
//
|
|
|
|
import SwiftUI
|
|
import SwiftData
|
|
import AVKit
|
|
|
|
struct MainView: View {
|
|
@Environment(\.modelContext) var ctx
|
|
|
|
@State private var scannedImages: [UIImage] = []
|
|
@State private var isShowingVNDocumentCameraView = false
|
|
@State private var isShowingSettingsView = false
|
|
|
|
@Query(sort: \Scan.timestamp, order: .reverse) var scans: [Scan]
|
|
|
|
@AppStorage(Prefs.autoLaunchCamera) var autolaunch = false
|
|
@AppStorage(Prefs.autoCopy) var autoCopy = false
|
|
|
|
var isAuthorized: Bool {
|
|
get async {
|
|
let status = AVCaptureDevice.authorizationStatus(for: .video)
|
|
|
|
// Determine if the user previously authorized camera access.
|
|
var isAuthorized = status == .authorized
|
|
|
|
// If the system hasn't determined the user's authorization status,
|
|
// explicitly prompt them for approval.
|
|
if status == .notDetermined {
|
|
isAuthorized = await AVCaptureDevice.requestAccess(for: .video)
|
|
}
|
|
|
|
return isAuthorized
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
NavigationView {
|
|
ScrollView {
|
|
// newScanButton
|
|
ForEach(scans, id: \.self) { scan in
|
|
ScanItemView(scan)
|
|
}
|
|
}
|
|
.onAppear {
|
|
if autolaunch {
|
|
isShowingVNDocumentCameraView = true
|
|
}
|
|
}
|
|
.navigationTitle("Just Scan It!")
|
|
.sheet(isPresented: $isShowingVNDocumentCameraView, onDismiss: saveImages) {
|
|
VNDocumentCameraViewControllerRepresentable(scanResult: $scannedImages)
|
|
}
|
|
.sheet(isPresented: $isShowingSettingsView) {
|
|
SettingsView()
|
|
}
|
|
.toolbar {
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
Button(action: { isShowingSettingsView.toggle() }) {
|
|
Image(systemName: "gear")
|
|
}
|
|
}
|
|
ToolbarItem {
|
|
Button(action: showVNDocumentCameraView) {
|
|
Image(systemName: "plus")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var newScanButton: some View {
|
|
Button { showVNDocumentCameraView() } label: {
|
|
Text("New Scan")
|
|
.frame(maxWidth: .infinity)
|
|
.padding(12)
|
|
.foregroundStyle(.white)
|
|
.background(.blue)
|
|
.clipShape(RoundedRectangle(cornerRadius: 15))
|
|
}
|
|
.padding(.horizontal)
|
|
}
|
|
|
|
private func showVNDocumentCameraView() {
|
|
Task { guard await isAuthorized else { return } }
|
|
|
|
isShowingVNDocumentCameraView = true
|
|
}
|
|
|
|
private func saveImages() {
|
|
guard !scannedImages.isEmpty else { return }
|
|
|
|
let newScan = Scan(images: scannedImages)
|
|
|
|
withAnimation(.easeIn) {
|
|
ctx.insert(newScan)
|
|
try? ctx.save()
|
|
}
|
|
|
|
if autoCopy { newScan.copyImages() }
|
|
|
|
scannedImages = []
|
|
}
|
|
}
|
|
|
|
#Preview {
|
|
let config = ModelConfiguration(isStoredInMemoryOnly: true)
|
|
let container = try! ModelContainer(for: Scan.self, configurations: config)
|
|
|
|
let scan = Scan(images: [UIImage(systemName: "questionmark")!])
|
|
container.mainContext.insert(scan)
|
|
|
|
return MainView().modelContainer(container)
|
|
}
|