mirror of
https://github.com/leonboe1/QuickDrop.git
synced 2026-11-11 02:51:11 +00:00
WIP: Add SwiftUI browse view
This commit is contained in:
1 parent
273b7459d8
commit
f18649b959
4 files changed
+130
-12
No files matched your search
@@ -44,7 +44,7 @@ public protocol ShareExtensionDelegate: AnyObject {
|
||||
}
|
||||
|
||||
|
||||
public struct RemoteDeviceInfo {
|
||||
public struct RemoteDeviceInfo: Identifiable, Equatable {
|
||||
public let name: String
|
||||
public let type: DeviceType
|
||||
public var id: String?
|
||||
|
||||
@@ -19,6 +19,8 @@ class SleepManager {
|
||||
|
||||
#if os(macOS)
|
||||
private var assertionID: IOPMAssertionID = 0
|
||||
#else
|
||||
private var assertionID: Int = 0
|
||||
#endif
|
||||
|
||||
private var timer: Timer?
|
||||
@@ -33,11 +35,12 @@ class SleepManager {
|
||||
}
|
||||
|
||||
private func disableSleep() {
|
||||
#if os(macOS)
|
||||
|
||||
if assertionID != 0 { return }
|
||||
|
||||
log("[SleepManager] Enabling Wakelock")
|
||||
|
||||
|
||||
#if os(macOS)
|
||||
IOPMAssertionCreateWithName(
|
||||
kIOPMAssertionTypePreventUserIdleDisplaySleep as CFString,
|
||||
IOPMAssertionLevel(kIOPMAssertionLevelOn),
|
||||
@@ -45,23 +48,23 @@ class SleepManager {
|
||||
&assertionID
|
||||
)
|
||||
#elseif os(iOS)
|
||||
log("[SleepManager] Keeping screen awake (iOS)")
|
||||
UIApplication.shared.isIdleTimerDisabled = true
|
||||
assertionID = 1
|
||||
#endif
|
||||
}
|
||||
|
||||
private func enableSleep() {
|
||||
#if os(macOS)
|
||||
if assertionID == 0 { return }
|
||||
|
||||
log("[SleepManager] Disabling Wakelock")
|
||||
|
||||
#if os(macOS)
|
||||
IOPMAssertionRelease(assertionID)
|
||||
assertionID = 0
|
||||
#elseif os(iOS)
|
||||
log("[SleepManager] Allowing screen to sleep (iOS)")
|
||||
UIApplication.shared.isIdleTimerDisabled = false
|
||||
#endif
|
||||
|
||||
assertionID = 0
|
||||
}
|
||||
|
||||
private func updateSleepState() {
|
||||
|
||||
@@ -8,14 +8,54 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ContentView: View {
|
||||
var body: some View {
|
||||
DeviceListView()
|
||||
}
|
||||
}
|
||||
|
||||
struct DeviceListView: View {
|
||||
@StateObject var model = ShareViewModel()
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
Image(systemName: "globe")
|
||||
.imageScale(.large)
|
||||
.foregroundStyle(.tint)
|
||||
Text("Hello, world!")
|
||||
Text("Available Devices")
|
||||
.font(.title)
|
||||
.padding()
|
||||
|
||||
if model.foundDevices.isEmpty {
|
||||
Text("Searching for devices...")
|
||||
.italic()
|
||||
.padding()
|
||||
} else {
|
||||
List(model.foundDevices) { device in
|
||||
HStack {
|
||||
Image(systemName: "smartphone")
|
||||
.resizable()
|
||||
.frame(width: 30, height: 30)
|
||||
Text(device.name.isEmpty ? "Android" : device.name)
|
||||
Spacer()
|
||||
|
||||
if model.selectedDevice == device {
|
||||
ProgressView()
|
||||
.progressViewStyle(CircularProgressViewStyle())
|
||||
}
|
||||
}
|
||||
.contentShape(Rectangle()) // Make entire row tappable
|
||||
.onTapGesture {
|
||||
model.selectDevice(device: device)
|
||||
}
|
||||
.background(model.selectedDevice == device ? Color.blue.opacity(0.2) : Color.clear)
|
||||
}
|
||||
.listStyle(PlainListStyle())
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.frame(minWidth: 300, minHeight: 400)
|
||||
}
|
||||
}
|
||||
|
||||
struct DeviceListView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
DeviceListView()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//
|
||||
// Model.swift
|
||||
// QuickDrop
|
||||
//
|
||||
// Created by Leon Böttger on 28.07.25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
class ShareViewModel: ObservableObject, ShareExtensionDelegate {
|
||||
|
||||
@Published var foundDevices: [RemoteDeviceInfo] = []
|
||||
@Published var selectedDevice: RemoteDeviceInfo?
|
||||
@Published var lastError: Error?
|
||||
|
||||
@Published var progressState: String? = nil
|
||||
@Published var progressValue: Double? = nil
|
||||
|
||||
private var urls: [URL] = []
|
||||
private var textToSend: String? = nil
|
||||
//private var errorAlertHandler = ErrorAlertHandler.shared
|
||||
|
||||
private var connectionEstablished = false
|
||||
private var timeoutDispatchWorkItem: DispatchWorkItem? = nil
|
||||
|
||||
init() {
|
||||
NearbyConnectionManager.shared.startDeviceDiscovery()
|
||||
}
|
||||
|
||||
func addDevice(device: RemoteDeviceInfo) {
|
||||
withAnimation {
|
||||
foundDevices.append(device)
|
||||
}
|
||||
}
|
||||
|
||||
func removeDevice(id: String) {
|
||||
withAnimation {
|
||||
foundDevices.removeAll { $0.id == id }
|
||||
}
|
||||
}
|
||||
|
||||
func connectionWasEstablished(pinCode: String) {
|
||||
connectionEstablished = true
|
||||
progressState = String(format: "PinCode".localized(), arguments: [pinCode])
|
||||
progressValue = 0
|
||||
}
|
||||
|
||||
func connectionFailed(with error: any Error) {
|
||||
progressValue = nil
|
||||
lastError = error
|
||||
|
||||
//ErrorAlertHandler.shared.showErrorAlert(for: chosenDevice?.name ?? "", error: error)
|
||||
}
|
||||
|
||||
func transferAccepted() {
|
||||
progressState = "Sending".localized()
|
||||
}
|
||||
|
||||
func transferProgress(progress: Double) {
|
||||
progressValue = progress
|
||||
}
|
||||
|
||||
func transferFinished() {
|
||||
progressState = "TransferFinished".localized()
|
||||
}
|
||||
|
||||
func selectDevice(device: RemoteDeviceInfo) {
|
||||
NearbyConnectionManager.shared.stopDeviceDiscovery()
|
||||
|
||||
progressValue = 0
|
||||
progressState = "Connecting".localized()
|
||||
selectedDevice = device
|
||||
NearbyConnectionManager.shared.startOutgoingTransfer(deviceID: device.id!, delegate: self, urls: urls, textToSend: textToSend)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user