proofmode 0.9.0

Capture, share, and preserve verifiable photos and videos
Documentation
import SwiftUI

struct ContentView: View {
    @EnvironmentObject var proofViewModel: ProofViewModel
    @EnvironmentObject var permissionService: PermissionService
    @State private var selectedTab = 0
    @State private var showingImagePicker = false
    @State private var showingCamera = false
    @State private var selectedProof: Proof?
    
    var body: some View {
        TabView(selection: $selectedTab) {
            // Generate Tab
            NavigationStack {
                VStack(spacing: 20) {
                    Text("Generate Proof")
                        .font(.largeTitle)
                        .fontWeight(.bold)
                        .padding(.top)
                    
                    Text("Create cryptographic proofs for your photos")
                        .font(.subheadline)
                        .foregroundColor(.secondary)
                        .multilineTextAlignment(.center)
                        .padding(.horizontal)
                    
                    Spacer()
                    
                    VStack(spacing: 16) {
                        // Camera Button
                        Button(action: {
                            checkCameraPermissionAndShow()
                        }) {
                            HStack {
                                Image(systemName: "camera.fill")
                                    .font(.title2)
                                Text("Take Photo")
                                    .font(.headline)
                            }
                            .frame(maxWidth: .infinity)
                            .padding()
                            .background(Color.blue)
                            .foregroundColor(.white)
                            .cornerRadius(12)
                        }
                        
                        // Photo Library Button
                        Button(action: {
                            checkPhotoLibraryPermissionAndShow()
                        }) {
                            HStack {
                                Image(systemName: "photo.on.rectangle")
                                    .font(.title2)
                                Text("Choose from Library")
                                    .font(.headline)
                            }
                            .frame(maxWidth: .infinity)
                            .padding()
                            .background(Color.green)
                            .foregroundColor(.white)
                            .cornerRadius(12)
                        }
                    }
                    .padding(.horizontal)
                    
                    Spacer()
                    
                    // Progress View
                    if proofViewModel.isGenerating {
                        VStack(spacing: 12) {
                            ProgressView()
                                .scaleEffect(1.5)
                            Text("Generating proof...")
                                .font(.headline)
                            if !proofViewModel.currentStatus.isEmpty {
                                Text(proofViewModel.currentStatus)
                                    .font(.caption)
                                    .foregroundColor(.secondary)
                            }
                        }
                        .padding()
                        .background(Color.gray.opacity(0.1))
                        .cornerRadius(12)
                        .padding(.horizontal)
                    }
                    
                    Spacer()
                }
                .navigationBarHidden(true)
            }
            .tabItem {
                Label("Generate", systemImage: "plus.circle")
            }
            .tag(0)
            
            // Verify Tab
            NavigationStack {
                VerifyView(selectedProof: $selectedProof)
                    .navigationTitle("Verify")
            }
            .tabItem {
                Label("Verify", systemImage: "checkmark.shield")
            }
            .tag(1)
            
            // Settings Tab
            NavigationStack {
                SettingsView()
                    .navigationTitle("Settings")
            }
            .tabItem {
                Label("Settings", systemImage: "gear")
            }
            .tag(2)
        }
        .sheet(isPresented: $showingImagePicker) {
            ImagePicker(sourceType: .photoLibrary) { image in
                proofViewModel.createProof(for: image)
            }
        }
        .fullScreenCover(isPresented: $showingCamera) {
            CameraView { image in
                showingCamera = false
                proofViewModel.createProof(for: image)
            }
        }
        .sheet(item: $selectedProof) { proof in
            NavigationStack {
                ProofDetailView(proof: proof)
                    .navigationTitle("Proof Details")
                    .navigationBarTitleDisplayMode(.inline)
                    .toolbar {
                        ToolbarItem(placement: .navigationBarTrailing) {
                            Button("Done") {
                                selectedProof = nil
                            }
                        }
                    }
            }
        }
        .alert("Success", isPresented: $proofViewModel.showingSuccess) {
            Button("OK") {
                selectedTab = 1 // Switch to Verify tab
            }
        } message: {
            Text(proofViewModel.successMessage)
        }
        .alert("Error", isPresented: $proofViewModel.showingError) {
            Button("OK") { }
        } message: {
            Text(proofViewModel.errorMessage)
        }
    }
    
    private func checkCameraPermissionAndShow() {
        permissionService.requestCameraPermission { granted in
            if granted {
                showingCamera = true
            }
        }
    }
    
    private func checkPhotoLibraryPermissionAndShow() {
        permissionService.requestPhotoLibraryPermission { granted in
            if granted {
                showingImagePicker = true
            }
        }
    }
}

struct SettingsView: View {
    @EnvironmentObject var proofViewModel: ProofViewModel
    @AppStorage("includeLocation") private var includeLocation = true
    @AppStorage("includeDeviceInfo") private var includeDeviceInfo = true
    @AppStorage("includeNetworkInfo") private var includeNetworkInfo = true
    
    var body: some View {
        Form {
            Section("Proof Options") {
                Toggle("Include Location", isOn: $includeLocation)
                Toggle("Include Device Info", isOn: $includeDeviceInfo)
                Toggle("Include Network Info", isOn: $includeNetworkInfo)
            }
            
            Section("Storage") {
                HStack {
                    Text("Proof Count")
                    Spacer()
                    Text("\(proofViewModel.proofs.count)")
                        .foregroundColor(.secondary)
                }
                
                Button("Clear All Proofs") {
                    proofViewModel.clearAllProofs()
                }
                .foregroundColor(.red)
            }
            
            Section("About") {
                HStack {
                    Text("Version")
                    Spacer()
                    Text(getVersion())
                        .foregroundColor(.secondary)
                }
                
                Link("Guardian Project", destination: URL(string: "https://guardianproject.info")!)
                Link("ProofMode Documentation", destination: URL(string: "https://proofmode.org")!)
            }
        }
    }
}

#Preview {
    ContentView()
        .environmentObject(ProofViewModel())
        .environmentObject(PermissionService())
}