mirror of
https://github.com/leonboe1/QuickDrop.git
synced 2026-11-11 19:11:10 +00:00
213 lines
7.6 KiB
Swift
213 lines
7.6 KiB
Swift
//
|
|
// ReceiveModel.swift
|
|
// QuickDrop
|
|
//
|
|
// Created by Leon Böttger on 16.08.25.
|
|
//
|
|
|
|
import SwiftUI
|
|
import StoreKit
|
|
import UserNotifications
|
|
|
|
#if os(macOS)
|
|
import BezelNotification
|
|
#else
|
|
import LUI
|
|
#endif
|
|
|
|
class ReceiveModel: ObservableObject, InboundAppDelegate {
|
|
|
|
let controlPlusScreen: (Bool) -> Void
|
|
|
|
init(controlPlusScreen: @escaping (Bool) -> Void = { _ in }) {
|
|
self.controlPlusScreen = controlPlusScreen
|
|
NearbyConnectionManager.shared.mainAppDelegate = self
|
|
NearbyConnectionManager.shared.becomeVisible()
|
|
}
|
|
|
|
|
|
func obtainUserConsent(transfer: TransferMetadata, device: RemoteDeviceInfo, acceptAutomatically: Bool) {
|
|
|
|
#if os(macOS)
|
|
NSApp.activate(ignoringOtherApps: true)
|
|
AudioManager.playIncomingFileSound()
|
|
#endif
|
|
|
|
let fileStr: String
|
|
|
|
if let textTitle = transfer.textDescription {
|
|
fileStr = textTitle
|
|
} else if transfer.files.count == 1 {
|
|
fileStr = transfer.files[0].name
|
|
} else {
|
|
fileStr = String.localizedStringWithFormat("NFiles".localized(), transfer.files.count)
|
|
}
|
|
|
|
|
|
let mainMessage: String
|
|
let name = device.name ?? "Android"
|
|
|
|
switch transfer.type {
|
|
case .file:
|
|
mainMessage = String(format: (acceptAutomatically ? "DeviceCurrentlySendingFiles" : "DeviceSendingFiles").localized(), arguments: [name, fileStr])
|
|
|
|
case .text:
|
|
mainMessage = String(format: (acceptAutomatically ? "DeviceCurrentlySendingText" : "DeviceSendingText").localized(), arguments: [name, fileStr])
|
|
|
|
case .url:
|
|
mainMessage = String(format: (acceptAutomatically ? "DeviceCurrentlySendingUrl" : "DeviceSendingUrl").localized(), arguments: [name, fileStr])
|
|
}
|
|
|
|
|
|
let pinCodeMessage = String(format: "PinCode".localized(), arguments: [transfer.pinCode ?? "?"])
|
|
let transferID = transfer.id
|
|
|
|
#if os(macOS)
|
|
let isMac = true
|
|
#else
|
|
let isMac = false
|
|
#endif
|
|
|
|
|
|
if acceptAutomatically && isMac {
|
|
pressAcceptButton(transferID: transfer.id, trustDevice: false)
|
|
|
|
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) { granted, _ in
|
|
if granted {
|
|
log("[ReceiveModel] User granted notification permissions")
|
|
|
|
let notificationContent = UNMutableNotificationContent()
|
|
notificationContent.title = "QuickDrop"
|
|
notificationContent.body = mainMessage
|
|
notificationContent.sound = nil
|
|
let notificationId = UUID().uuidString
|
|
|
|
let notificationReq = UNNotificationRequest(identifier: notificationId, content: notificationContent, trigger: nil)
|
|
UNUserNotificationCenter.current().add(notificationReq)
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
|
|
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [notificationId])
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
|
|
let title = "QuickDrop - \(pinCodeMessage)"
|
|
let primaryButtonTitle = "Accept".localized()
|
|
let primaryButtonAction = { (trustDevice: Bool) in self.pressAcceptButton(transferID: transferID, trustDevice: trustDevice) }
|
|
let secondaryButtonTitle = "Decline".localized()
|
|
let secondaryButtonAction = { NearbyConnectionManager.shared.submitUserConsent(transferID: transferID, accept: false, trustDevice: false, storeInTemp: false) }
|
|
|
|
#if os(macOS)
|
|
let alert = NSAlert()
|
|
alert.alertStyle = .informational
|
|
|
|
alert.messageText = title
|
|
alert.informativeText = mainMessage
|
|
alert.addButton(withTitle: primaryButtonTitle)
|
|
alert.addButton(withTitle: secondaryButtonTitle)
|
|
|
|
if transfer.allowsToBeAddedAsTrustedDevice {
|
|
alert.showsSuppressionButton = true
|
|
alert.suppressionButton?.title = "AutoAcceptFromThisDevice".localized()
|
|
}
|
|
|
|
let result = alert.runModal()
|
|
|
|
if result == .alertFirstButtonReturn {
|
|
primaryButtonAction(alert.suppressionButton?.state == .on)
|
|
} else if result == .alertSecondButtonReturn {
|
|
secondaryButtonAction()
|
|
}
|
|
#else
|
|
// iOS
|
|
let alwaysAcceptLabel = transfer.allowsToBeAddedAsTrustedDevice ? "AlwaysAccept".localized() : nil
|
|
ProgressAlert.shared.askForUserPermission(title: title, message: mainMessage, acceptLabel: primaryButtonTitle, acceptAlwaysLabel: alwaysAcceptLabel, rejectLabel: secondaryButtonTitle, acceptAutomatically: acceptAutomatically) { accepted in
|
|
|
|
switch accepted {
|
|
case .Accept:
|
|
primaryButtonAction(false)
|
|
case .AcceptAlways:
|
|
primaryButtonAction(true)
|
|
case .Decline:
|
|
secondaryButtonAction()
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
func transferProgress(progress: Double) {
|
|
#if os(iOS)
|
|
ProgressAlert.shared.updateProgress(progress)
|
|
#endif
|
|
}
|
|
|
|
|
|
func connectionWasTerminated(from device: RemoteDeviceInfo, wasPlainTextTransfer: Bool, error: (any Error)?) {
|
|
|
|
#if os(macOS)
|
|
finish()
|
|
#else
|
|
ProgressAlert.shared.updateProgress(nil) {
|
|
finish()
|
|
}
|
|
#endif
|
|
|
|
func finish() {
|
|
if let error = error {
|
|
|
|
#if os(iOS)
|
|
errorVibration()
|
|
#endif
|
|
|
|
controlPlusScreen(false)
|
|
ErrorAlertHandler.shared.showErrorAlert(for: device.name ?? "Android", error: error)
|
|
} else {
|
|
|
|
#if os(iOS)
|
|
doubleVibration()
|
|
#endif
|
|
|
|
if wasPlainTextTransfer {
|
|
showCopiedToClipboardAlert()
|
|
}
|
|
|
|
let currentCount = Settings.shared.incomingTransmissionCount
|
|
|
|
#if os(macOS)
|
|
if currentCount == 0 {
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
SKStoreReviewController.requestReview()
|
|
}
|
|
}
|
|
#endif
|
|
|
|
Settings.shared.incomingTransmissionCount = currentCount + 1
|
|
log("[ReceiveModel] Successful transmission. Current count: \(currentCount)")
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private func showCopiedToClipboardAlert() {
|
|
#if os(macOS)
|
|
DispatchQueue.main.async {
|
|
BezelNotification.show(messageText: "InsertedIntoClipboard".localized(), icon: .clipboard)
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
private func pressAcceptButton(transferID: String, trustDevice: Bool) {
|
|
if isFileTransferRestricted() {
|
|
log("[ReceiveModel] Showing plus screen...")
|
|
NearbyConnectionManager.shared.submitUserConsent(transferID: transferID, accept: true, trustDevice: trustDevice, storeInTemp: true)
|
|
controlPlusScreen(true)
|
|
} else {
|
|
NearbyConnectionManager.shared.submitUserConsent(transferID: transferID, accept: true, trustDevice: trustDevice, storeInTemp: false)
|
|
}
|
|
}
|
|
}
|