mirror of
https://github.com/FBukovina/Atoll.git
synced 2026-10-27 15:14:33 +00:00
Restored files from old Mac, force pushing
This commit is contained in:
parent
5dd95228b8
commit
5040381840
126 changed files with 10431 additions and 67 deletions
122
DynamicIsland/components/Webcam/WebcamView.swift
Normal file
122
DynamicIsland/components/Webcam/WebcamView.swift
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
//
|
||||
// WebcamView.swift
|
||||
// boringNotch
|
||||
//
|
||||
// Created by Harsh Vardhan Goswami on 19/08/24.
|
||||
//
|
||||
|
||||
import AVFoundation
|
||||
import Defaults
|
||||
import SwiftUI
|
||||
|
||||
struct CameraPreviewView: View {
|
||||
@EnvironmentObject var vm: DynamicIslandViewModel
|
||||
@ObservedObject var webcamManager: WebcamManager
|
||||
|
||||
// Track if authorization request is in progress to avoid multiple requests
|
||||
@State private var isRequestingAuthorization: Bool = false
|
||||
|
||||
var body: some View {
|
||||
GeometryReader { geometry in
|
||||
ZStack {
|
||||
if let previewLayer = webcamManager.previewLayer {
|
||||
CameraPreviewLayerView(previewLayer: previewLayer)
|
||||
.scaleEffect(x: -1, y: 1)
|
||||
.clipShape(RoundedRectangle(cornerRadius: Defaults[.mirrorShape] == .rectangle ? !Defaults[.cornerRadiusScaling] ? MusicPlayerImageSizes.cornerRadiusInset.closed : MusicPlayerImageSizes.cornerRadiusInset.opened : 100))
|
||||
.frame(width: geometry.size.width, height: geometry.size.width)
|
||||
.opacity(webcamManager.isSessionRunning ? 1 : 0)
|
||||
}
|
||||
|
||||
if !webcamManager.isSessionRunning {
|
||||
ZStack {
|
||||
RoundedRectangle(cornerRadius: Defaults[.mirrorShape] == .rectangle ? !Defaults[.cornerRadiusScaling] ? MusicPlayerImageSizes.cornerRadiusInset.closed : 12 : 100)
|
||||
.fill(Color(red: 20/255, green: 20/255, blue: 20/255))
|
||||
.strokeBorder(.white.opacity(0.04), lineWidth: 1)
|
||||
.frame(width: geometry.size.width, height: geometry.size.width)
|
||||
VStack(spacing: 8) {
|
||||
Image(systemName: webcamManager.authorizationStatus == .denied ? "exclamationmark.triangle" : "web.camera")
|
||||
.foregroundStyle(.gray)
|
||||
.font(.system(size: geometry.size.width/3.5))
|
||||
Text(webcamManager.authorizationStatus == .denied ? "Access Denied" : "Mirror")
|
||||
.font(.caption2)
|
||||
.foregroundColor(.gray)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.onTapGesture {
|
||||
handleCameraTap()
|
||||
}
|
||||
.onDisappear {
|
||||
webcamManager.stopSession()
|
||||
}
|
||||
}
|
||||
.aspectRatio(1, contentMode: .fit)
|
||||
}
|
||||
|
||||
private func handleCameraTap() {
|
||||
if isRequestingAuthorization {
|
||||
return // Prevent multiple authorization requests
|
||||
}
|
||||
|
||||
switch webcamManager.authorizationStatus {
|
||||
case .authorized:
|
||||
if webcamManager.isSessionRunning {
|
||||
webcamManager.stopSession()
|
||||
} else if webcamManager.cameraAvailable {
|
||||
webcamManager.startSession()
|
||||
}
|
||||
case .denied, .restricted:
|
||||
DispatchQueue.main.async {
|
||||
NSApp.setActivationPolicy(.regular)
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
let alert = NSAlert()
|
||||
alert.messageText = "Camera Access Required"
|
||||
alert.informativeText = "Please allow camera access in System Settings to use the mirror feature."
|
||||
alert.addButton(withTitle: "Open Settings")
|
||||
alert.addButton(withTitle: "Cancel")
|
||||
|
||||
if alert.runModal() == .alertFirstButtonReturn {
|
||||
if let settingsURL = URL(string: "x-apple.systempreferences:com.apple.preference.security?Privacy_Camera") {
|
||||
NSWorkspace.shared.open(settingsURL)
|
||||
}
|
||||
}
|
||||
NSApp.setActivationPolicy(.accessory)
|
||||
NSApp.deactivate()
|
||||
}
|
||||
case .notDetermined:
|
||||
isRequestingAuthorization = true
|
||||
webcamManager.checkAndRequestVideoAuthorization()
|
||||
// Reset the request flag after a reasonable delay
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
|
||||
isRequestingAuthorization = false
|
||||
}
|
||||
@unknown default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CameraPreviewLayerView: NSViewRepresentable {
|
||||
let previewLayer: AVCaptureVideoPreviewLayer
|
||||
|
||||
func makeNSView(context: Context) -> NSView {
|
||||
let view = NSView(frame: .zero)
|
||||
previewLayer.frame = view.bounds
|
||||
previewLayer.videoGravity = .resizeAspectFill
|
||||
view.layer = previewLayer
|
||||
view.wantsLayer = true
|
||||
return view
|
||||
}
|
||||
|
||||
func updateNSView(_ nsView: NSView, context: Context) {
|
||||
CATransaction.begin()
|
||||
CATransaction.setDisableActions(true)
|
||||
previewLayer.frame = nsView.bounds
|
||||
CATransaction.commit()
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
CameraPreviewView(webcamManager: WebcamManager())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue