Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66acbf25a3 | ||
|
|
93537094e4 | ||
|
|
b6b11c00c0 | ||
|
|
92671d8983 | ||
|
|
bfc23fde15 | ||
|
|
a39a5a324a | ||
|
|
fd7dfd959b | ||
|
|
bd4b181a49 | ||
|
|
f066a11608 | ||
|
|
5429126c1e | ||
|
|
4bf8a9052d | ||
|
|
f786af9d12 | ||
|
|
6def7dbc9f | ||
|
|
fcc0ce0818 | ||
|
|
fd6978cc90 | ||
|
|
12ef87c4da | ||
|
|
518fabcd33 | ||
|
|
eb6bb8fc4d | ||
|
|
d443412697 | ||
|
|
110b0a4ae7 | ||
|
|
2b272c81c1 | ||
|
|
11afc232ab | ||
|
|
943414db58 | ||
|
|
b135229d30 | ||
|
|
6126d9428d |
No files matched your search
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
|
Before Width: | Height: | Size: 488 KiB |
|
Before Width: | Height: | Size: 492 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 488 KiB |
|
Before Width: | Height: | Size: 492 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 104 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 105 KiB After Width: | Height: | Size: 105 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 1.2 MiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@@ -392,6 +392,13 @@ class InboundNearbyConnection: NearbyConnection {
|
||||
|
||||
let pkeFrame = frame.v1.pairedKeyEncryption
|
||||
|
||||
if frame.v1.certificateInfo.publicCertificate.isEmpty {
|
||||
log("[InboundNearbyConnection \(self.id)] Detected legacy peer.")
|
||||
}
|
||||
else {
|
||||
log("[InboundNearbyConnection \(self.id)] Detected QuickDrop peer.")
|
||||
}
|
||||
|
||||
// Check if we can accept the connection automatically
|
||||
if !pkeFrame.secretIDHash.isEmpty,
|
||||
let trustedCertData = TrustStore.shared.findTrustedKey(for: pkeFrame.secretIDHash),
|
||||
@@ -461,9 +468,11 @@ class InboundNearbyConnection: NearbyConnection {
|
||||
}
|
||||
|
||||
|
||||
private func makeFileDestinationURL(_ initialDest: URL) -> URL {
|
||||
private func makeFileDestinationURL(_ initialDest: URL, usedDestinations: Set<URL>) -> URL {
|
||||
var dest = initialDest
|
||||
if FileManager.default.fileExists(atPath: dest.path) {
|
||||
let fm = FileManager.default
|
||||
|
||||
if fm.fileExists(atPath: dest.path) || usedDestinations.contains(dest) {
|
||||
var counter = 1
|
||||
var path: String
|
||||
let ext = dest.pathExtension
|
||||
@@ -474,8 +483,8 @@ class InboundNearbyConnection: NearbyConnection {
|
||||
path += ".\(ext)"
|
||||
}
|
||||
counter += 1
|
||||
} while FileManager.default.fileExists(atPath: path)
|
||||
dest = URL(fileURLWithPath: path)
|
||||
dest = URL(fileURLWithPath: path)
|
||||
} while fm.fileExists(atPath: dest.path) || usedDestinations.contains(dest)
|
||||
}
|
||||
return dest
|
||||
}
|
||||
@@ -487,12 +496,18 @@ class InboundNearbyConnection: NearbyConnection {
|
||||
|
||||
if frame.v1.introduction.fileMetadata.count > 0 && frame.v1.introduction.textMetadata.isEmpty {
|
||||
let saveDirectory = SaveFilesManager.shared.getSaveDirectory()
|
||||
var usedDestinations = Set<URL>()
|
||||
|
||||
for file in frame.v1.introduction.fileMetadata {
|
||||
let dest = makeFileDestinationURL(saveDirectory.appendingPathComponent(file.name))
|
||||
let info = InternalFileInfo(meta: FileMetadata(name: file.name, size: file.size, mimeType: file.mimeType),
|
||||
payloadID: file.payloadID,
|
||||
destinationURL: dest)
|
||||
let initialDest = saveDirectory.appendingPathComponent(file.name)
|
||||
let dest = makeFileDestinationURL(initialDest, usedDestinations: usedDestinations)
|
||||
usedDestinations.insert(dest)
|
||||
|
||||
let info = InternalFileInfo(
|
||||
meta: FileMetadata(name: file.name, size: file.size, mimeType: file.mimeType),
|
||||
payloadID: file.payloadID,
|
||||
destinationURL: dest
|
||||
)
|
||||
filesToBeReceived[file.payloadID] = info
|
||||
bytesToBeTransferred += file.size
|
||||
}
|
||||
@@ -524,7 +539,7 @@ class InboundNearbyConnection: NearbyConnection {
|
||||
|
||||
func checkIfCanProceed(metadata: TransferMetadata) {
|
||||
|
||||
let acceptAutomatically = isAuthenticated || UserDefaults.standard.bool(forKey: UserDefaultsKeys.automaticallyAcceptFiles.rawValue)
|
||||
let acceptAutomatically = isAuthenticated || Settings.shared.automaticallyAcceptFiles
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.obtainUserConsent(transfer: metadata, device: self.remoteDeviceInfo!, connection: self, acceptAutomatically: acceptAutomatically)
|
||||
@@ -638,12 +653,7 @@ class InboundNearbyConnection: NearbyConnection {
|
||||
#endif
|
||||
|
||||
guard file.created else { continue }
|
||||
do {
|
||||
try FileManager.default.removeItem(at: file.destinationURL)
|
||||
}
|
||||
catch {
|
||||
// if it fails, we don't care. Could be because file was not created yet
|
||||
}
|
||||
try? FileManager.default.removeItem(at: file.destinationURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#if os(iOS)
|
||||
import UIKit
|
||||
import RNDeviceName
|
||||
import DeviceKit
|
||||
#endif
|
||||
|
||||
import Foundation
|
||||
@@ -16,6 +16,7 @@ import System
|
||||
import SwiftECC
|
||||
import CryptoKit
|
||||
import SwiftUI
|
||||
import QRCode
|
||||
|
||||
public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearbyConnectionDelegate, OutboundNearbyConnectionDelegate, ObservableObject {
|
||||
|
||||
@@ -44,12 +45,12 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
public static let shared = NearbyConnectionManager()
|
||||
|
||||
@Published var attachments: AttachmentDetails? = nil
|
||||
@Published var hasLocalNetworkAccess = true
|
||||
@Published var isConnectedViaWiFi = true
|
||||
@Published var hasLocalNetworkPermission = true
|
||||
@Published var isConnectedToLocalNetwork = true
|
||||
|
||||
public var connectionUpdateCallback: (Bool) -> Void = { _ in } {
|
||||
didSet {
|
||||
connectionUpdateCallback(isConnectedViaWiFi)
|
||||
connectionUpdateCallback(isConnectedToLocalNetwork)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,7 +59,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
#if os(macOS)
|
||||
self.deviceInfo = EndpointInfo(name: Host.current().localizedName ?? "Mac", deviceType: .computer)
|
||||
#else
|
||||
let marketingName = UIDevice.current.marketingName.withoutBracketedContent
|
||||
let marketingName = Device.current.description.withoutBracketedContent
|
||||
let isiPad = UIDevice.current.model == "iPad"
|
||||
|
||||
self.deviceInfo = EndpointInfo(name: marketingName, deviceType: isiPad ? .tablet : .phone)
|
||||
@@ -69,18 +70,23 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
super.init()
|
||||
|
||||
hasConnectionMonitor.pathUpdateHandler = { path in
|
||||
if path.usesInterfaceType(.wifi) {
|
||||
log("[NearbyConnectionManager] Connected via WiFi.")
|
||||
DispatchQueue.main.async {
|
||||
self.isConnectedViaWiFi = true
|
||||
self.connectionUpdateCallback(true)
|
||||
}
|
||||
} else {
|
||||
log("[NearbyConnectionManager] WiFi connection lost.")
|
||||
DispatchQueue.main.async {
|
||||
self.isConnectedViaWiFi = false
|
||||
self.connectionUpdateCallback(false)
|
||||
|
||||
#if os(macOS)
|
||||
// On Mac, the local network is available as long as the path is satisfied, since Macs do not have cellular modems
|
||||
let isConnected = path.status == .satisfied
|
||||
#else
|
||||
// On iPhone and iPad, the local network is only available using Wi-Fi or Ethernet
|
||||
let isConnected = path.usesInterfaceType(.wifi) || path.usesInterfaceType(.wiredEthernet)
|
||||
#endif
|
||||
|
||||
DispatchQueue.main.async {
|
||||
if isConnected {
|
||||
log("[NearbyConnectionManager] Connected to local network.")
|
||||
} else {
|
||||
log("[NearbyConnectionManager] Local network lost.")
|
||||
}
|
||||
self.isConnectedToLocalNetwork = isConnected
|
||||
self.connectionUpdateCallback(isConnected)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,12 +136,10 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
|
||||
|
||||
private static func generateEndpointID() -> [UInt8] {
|
||||
let userDefaultsKey = UserDefaultsKeys.endpointID.rawValue
|
||||
|
||||
// Try to retrieve from UserDefaults
|
||||
if let savedString = UserDefaults.standard.string(forKey: userDefaultsKey),
|
||||
let savedData = savedString.data(using: .utf8)
|
||||
{
|
||||
if let savedString = Settings.shared.endpointID,
|
||||
let savedData = savedString.data(using: .utf8) {
|
||||
return [UInt8](savedData)
|
||||
}
|
||||
|
||||
@@ -148,7 +152,7 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
|
||||
// Save to UserDefaults as String
|
||||
let idString = String(bytes: id, encoding: .utf8) ?? ""
|
||||
UserDefaults.standard.set(idString, forKey: userDefaultsKey)
|
||||
Settings.shared.endpointID = idString
|
||||
|
||||
return id
|
||||
}
|
||||
@@ -245,13 +249,13 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
log("[NearbyConnectionManager] Browser failed: \(error)")
|
||||
case .ready:
|
||||
log("[NearbyConnectionManager] Browser ready")
|
||||
self.hasLocalNetworkAccess = true
|
||||
self.hasLocalNetworkPermission = true
|
||||
case .waiting(let error):
|
||||
log("[NearbyConnectionManager] Browser waiting: \(error)")
|
||||
|
||||
if error == NWError.dns(DNSServiceErrorType(kDNSServiceErr_PolicyDenied)) {
|
||||
log("[NearbyConnectionManager] Local network access not granted.")
|
||||
self.hasLocalNetworkAccess = false
|
||||
self.hasLocalNetworkPermission = false
|
||||
}
|
||||
default:
|
||||
break
|
||||
@@ -394,13 +398,17 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
}
|
||||
|
||||
|
||||
public func generateQrCodeKey() -> String{
|
||||
public func generateQrCodeKey() -> Image? {
|
||||
|
||||
log("[NearbyConnectionManager] Generating new QR code key")
|
||||
|
||||
let domain = Domain.instance(curve: .EC256r1)
|
||||
let (pubKey, privKey) = domain.makeKeyPair()
|
||||
qrCodePrivateKey = privKey
|
||||
var keyData = Data()
|
||||
keyData.append(contentsOf: [0, 0, 2])
|
||||
let keyBytes = Data(pubKey.w.x.asSignedBytes())
|
||||
|
||||
// Sometimes, for some keys, there will be a leading zero byte. Strip that, Android really hates it (it breaks the endpoint info)
|
||||
keyData.append(keyBytes.suffixOfAtMost(numBytes: 32))
|
||||
|
||||
@@ -408,7 +416,26 @@ public class NearbyConnectionManager: NSObject, NetServiceDelegate, InboundNearb
|
||||
qrCodeAdvertisingToken = HKDF.deriveKey(ikm: ikm, salt: Data(), info: "advertisingContext".data(using: .utf8)!, outputLength: 16).data()
|
||||
qrCodeNameEncryptionKey = HKDF.deriveKey(ikm: ikm, salt: Data(), info: "encryptionKey".data(using: .utf8)!, outputLength: 16)
|
||||
|
||||
return keyData.urlSafeBase64EncodedString()
|
||||
|
||||
do {
|
||||
let qrKey = keyData.urlSafeBase64EncodedString()
|
||||
let qrCodeImage = try QRCode.build
|
||||
.text("https://quickshare.google/qrcode#key=\(qrKey)")
|
||||
.backgroundColor(CGColor(srgbRed: 1, green: 1, blue: 1, alpha: 0))
|
||||
.quietZonePixelCount(3)
|
||||
.onPixels.shape(.circle())
|
||||
.eye.shape(.squircle())
|
||||
.errorCorrection(.low)
|
||||
.generate
|
||||
.image(dimension: 1000)
|
||||
|
||||
return Image(decorative: qrCodeImage, scale: 1.0, orientation: .up)
|
||||
}
|
||||
catch {
|
||||
log("Error generating QR code: \(error)")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -110,23 +110,11 @@ extension String {
|
||||
}
|
||||
|
||||
|
||||
public enum UserDefaultsKeys: String, CaseIterable {
|
||||
case isEligibleForIap = "isEligibleForIap"
|
||||
case appLaunchedBefore = "ShowedWelcomeScreen"
|
||||
case plusVersion = "isPlusVersion"
|
||||
case transmissionCount = "reviewRequestCountKey"
|
||||
case automaticallyAcceptFiles = "automaticallyAcceptFiles"
|
||||
case saveFolderBookmark = "saveFolderBookmark"
|
||||
case openFinderAfterReceiving = "openFinderAfterReceiving"
|
||||
case endpointID = "endpointID"
|
||||
}
|
||||
|
||||
|
||||
public func isPlusVersion() -> Bool {
|
||||
public func fullVersion() -> Bool {
|
||||
|
||||
#if os(macOS)
|
||||
// Enable full functionality if app distributed directly
|
||||
return DistributionDetector.isDirectDistributionEnabled || UserDefaults.standard.bool(forKey: UserDefaultsKeys.plusVersion.rawValue)
|
||||
return Settings.shared.gotPlus || DistributionDetector.isDirectDistributionEnabled
|
||||
#else
|
||||
// iOS
|
||||
return true
|
||||
@@ -135,10 +123,5 @@ public func isPlusVersion() -> Bool {
|
||||
|
||||
|
||||
public func isFileTransferRestricted() -> Bool {
|
||||
(!isPlusVersion() && incomingTransmissionCount() > 1)
|
||||
}
|
||||
|
||||
|
||||
public func incomingTransmissionCount() -> Int {
|
||||
return UserDefaults.standard.integer(forKey: UserDefaultsKeys.transmissionCount.rawValue)
|
||||
(!fullVersion() && Settings.shared.incomingTransmissionCount > 1)
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class SaveFilesManager {
|
||||
|
||||
public func movePendingFilesToTarget() {
|
||||
|
||||
if isPlusVersion() {
|
||||
if fullVersion() {
|
||||
do {
|
||||
let fileManager = FileManager.default
|
||||
let files = try fileManager.contentsOfDirectory(at: tempDirectory, includingPropertiesForKeys: nil)
|
||||
@@ -119,7 +119,7 @@ public class SaveFilesManager {
|
||||
if !filesFinishedDownloadingSinceLastRun.isEmpty && !isFileTransferRestricted() {
|
||||
|
||||
#if os(macOS)
|
||||
if UserDefaults.standard.bool(forKey: UserDefaultsKeys.openFinderAfterReceiving.rawValue) {
|
||||
if Settings.shared.openFinderAfterReceiving {
|
||||
log("[SaveFilesManager] Opening \(filesFinishedDownloadingSinceLastRun.count) file(s) in Finder.")
|
||||
NSWorkspace.shared.activateFileViewerSelecting(filesFinishedDownloadingSinceLastRun)
|
||||
}
|
||||
@@ -171,7 +171,7 @@ public class SaveFilesManager {
|
||||
return securityScopeUrl
|
||||
}
|
||||
|
||||
if let bookmarkData = UserDefaults.standard.data(forKey: UserDefaultsKeys.saveFolderBookmark.rawValue) {
|
||||
if let bookmarkData = Settings.shared.saveFolderBookmark {
|
||||
var isStale = false
|
||||
|
||||
do {
|
||||
|
||||
@@ -17,6 +17,20 @@
|
||||
EB05DFBE2E59FC8900EF567A /* TrustedDevicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */; };
|
||||
EB05DFBF2E59FD0A00EF567A /* TrustedDevicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */; };
|
||||
EB05DFC02E5A2EAA00EF567A /* TrustedDevicesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */; };
|
||||
EB1325D32E701D8E00FD749C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325D22E701D8900FD749C /* Settings.swift */; };
|
||||
EB1325D42E701D8E00FD749C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325D22E701D8900FD749C /* Settings.swift */; };
|
||||
EB1325D52E701D8E00FD749C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325D22E701D8900FD749C /* Settings.swift */; };
|
||||
EB1325D62E701D8E00FD749C /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325D22E701D8900FD749C /* Settings.swift */; };
|
||||
EB1325EB2E7025D900FD749C /* ApIsolationTester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E92E7025D900FD749C /* ApIsolationTester.swift */; };
|
||||
EB1325EC2E7025D900FD749C /* ActiveNetworkInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E72E7025D900FD749C /* ActiveNetworkInterface.swift */; };
|
||||
EB1325ED2E7025D900FD749C /* ApIsolation6Tester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E82E7025D900FD749C /* ApIsolation6Tester.swift */; };
|
||||
EB1325F42E7025D900FD749C /* ApIsolationTester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E92E7025D900FD749C /* ApIsolationTester.swift */; };
|
||||
EB1325F52E7025D900FD749C /* ActiveNetworkInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E72E7025D900FD749C /* ActiveNetworkInterface.swift */; };
|
||||
EB1325F62E7025D900FD749C /* ApIsolation6Tester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325E82E7025D900FD749C /* ApIsolation6Tester.swift */; };
|
||||
EB1325F82E70288300FD749C /* SendToExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325F72E70287C00FD749C /* SendToExtension.swift */; };
|
||||
EB1325FA2E70288300FD749C /* SendToExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB1325F72E70287C00FD749C /* SendToExtension.swift */; };
|
||||
EB1325FD2E7034B000FD749C /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = EB1325FC2E7034B000FD749C /* InfoPlist.xcstrings */; };
|
||||
EB1325FE2E7034B000FD749C /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = EB1325FC2E7034B000FD749C /* InfoPlist.xcstrings */; };
|
||||
EB16B6122E58B4B9007D9792 /* IdentityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB16B6112E58B4B9007D9792 /* IdentityManager.swift */; };
|
||||
EB16B6132E58B4B9007D9792 /* IdentityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB16B6112E58B4B9007D9792 /* IdentityManager.swift */; };
|
||||
EB16B6142E58B4B9007D9792 /* IdentityManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB16B6112E58B4B9007D9792 /* IdentityManager.swift */; };
|
||||
@@ -97,16 +111,18 @@
|
||||
EB704A822E4A7BB3008E608F /* DistributionDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB704A812E4A7BAE008E608F /* DistributionDetector.swift */; };
|
||||
EB704A832E4B10D4008E608F /* DistributionDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB704A812E4A7BAE008E608F /* DistributionDetector.swift */; };
|
||||
EB704A842E4B10D4008E608F /* DistributionDetector.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB704A812E4A7BAE008E608F /* DistributionDetector.swift */; };
|
||||
EB721F242E75AFA900F2099F /* QuickDropIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = EB721F232E75AFA900F2099F /* QuickDropIcon.icon */; };
|
||||
EB721F252E75AFA900F2099F /* QuickDropIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = EB721F232E75AFA900F2099F /* QuickDropIcon.icon */; };
|
||||
EB7654782E525ACC006B4AA3 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = EB7654772E525ACC006B4AA3 /* MainMenu.xib */; };
|
||||
EB7654A12E53252D006B4AA3 /* AttachmentDetails.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB950B762E521712002D68FA /* AttachmentDetails.swift */; };
|
||||
EB7654C02E534A8E006B4AA3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69DA9A1329E0BF5200A442DA /* Assets.xcassets */; };
|
||||
EB7654C12E534A8E006B4AA3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69DA9A1329E0BF5200A442DA /* Assets.xcassets */; };
|
||||
EB7654C42E534E89006B4AA3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EB7654C32E534E89006B4AA3 /* InfoPlist.strings */; };
|
||||
EB7654C62E534E89006B4AA3 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = EB7654C32E534E89006B4AA3 /* InfoPlist.strings */; };
|
||||
EB7CD1452D6FB0C300CB0CB5 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7CD1442D6FB0C100CB0CB5 /* Logger.swift */; };
|
||||
EB7CD1462D6FB0E800CB0CB5 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7CD1442D6FB0C100CB0CB5 /* Logger.swift */; };
|
||||
EB7F54122D78E96000989564 /* TutorialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7F54112D78E95C00989564 /* TutorialView.swift */; };
|
||||
EB7F54142D78E9E700989564 /* LicenseWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7F54132D78E9E400989564 /* LicenseWindow.swift */; };
|
||||
EB821C992E76FE5300036963 /* SmallSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB96ED8A2D7F7CF4004B3FF1 /* SmallSheetView.swift */; };
|
||||
EB821C9A2E76FE5300036963 /* SmallSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB96ED8A2D7F7CF4004B3FF1 /* SmallSheetView.swift */; };
|
||||
EB886E522E4E19390052B7D9 /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB886E512E4E19390052B7D9 /* HKDF.swift */; };
|
||||
EB886E532E4E19390052B7D9 /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB886E512E4E19390052B7D9 /* HKDF.swift */; };
|
||||
EB886E542E4E19390052B7D9 /* HKDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB886E512E4E19390052B7D9 /* HKDF.swift */; };
|
||||
@@ -152,7 +168,6 @@
|
||||
EB950B612E520674002D68FA /* SwiftECC in Frameworks */ = {isa = PBXBuildFile; productRef = EB950B602E520674002D68FA /* SwiftECC */; };
|
||||
EB950B632E52067A002D68FA /* QRCode in Frameworks */ = {isa = PBXBuildFile; productRef = EB950B622E52067A002D68FA /* QRCode */; };
|
||||
EB950B652E52067D002D68FA /* LUI in Frameworks */ = {isa = PBXBuildFile; productRef = EB950B642E52067D002D68FA /* LUI */; };
|
||||
EB950B672E520680002D68FA /* RNDeviceName in Frameworks */ = {isa = PBXBuildFile; productRef = EB950B662E520680002D68FA /* RNDeviceName */; };
|
||||
EB950B6F2E5206E2002D68FA /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB950B6B2E5206E2002D68FA /* ShareViewController.swift */; };
|
||||
EB950B702E520734002D68FA /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = EB5C36922E34EBBD0052EFD7 /* Localizable.xcstrings */; };
|
||||
EB950B742E520957002D68FA /* Attachments.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB950B732E520954002D68FA /* Attachments.swift */; };
|
||||
@@ -173,7 +188,6 @@
|
||||
EB979F9A2E50CAA6008B8C5C /* PieProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB979F992E50CAA6008B8C5C /* PieProgressView.swift */; };
|
||||
EB97A00F2E511124008B8C5C /* ReceiveModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB97A00E2E511120008B8C5C /* ReceiveModel.swift */; };
|
||||
EB97A0102E51CD13008B8C5C /* ReceiveModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB97A00E2E511120008B8C5C /* ReceiveModel.swift */; };
|
||||
EB97A0132E51D6B2008B8C5C /* RNDeviceName in Frameworks */ = {isa = PBXBuildFile; productRef = EB97A0122E51D6B2008B8C5C /* RNDeviceName */; };
|
||||
EB97A0142E51DD00008B8C5C /* License.txt in Resources */ = {isa = PBXBuildFile; fileRef = EB5C36E32E34EC0E0052EFD7 /* License.txt */; };
|
||||
EB97A0152E51DD00008B8C5C /* timeIsNow.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = EBC05C8A2E33B59E00EECC18 /* timeIsNow.mp3 */; };
|
||||
EB97A01A2E51EAA2008B8C5C /* UIAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB97A0192E51EA9C008B8C5C /* UIAlert.swift */; };
|
||||
@@ -183,16 +197,13 @@
|
||||
EB9925852E45EF0900357055 /* QRCode in Frameworks */ = {isa = PBXBuildFile; productRef = EB9925842E45EF0900357055 /* QRCode */; };
|
||||
EB9925872E45F12F00357055 /* QRCode in Frameworks */ = {isa = PBXBuildFile; productRef = EB9925862E45F12F00357055 /* QRCode */; };
|
||||
EB9925892E45F13500357055 /* QRCode in Frameworks */ = {isa = PBXBuildFile; productRef = EB9925882E45F13500357055 /* QRCode */; };
|
||||
EBADEB8F2E8029750021B5E4 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = EBADEB8E2E8029750021B5E4 /* DeviceKit */; };
|
||||
EBADEB912E802A830021B5E4 /* DeviceKit in Frameworks */ = {isa = PBXBuildFile; productRef = EBADEB902E802A830021B5E4 /* DeviceKit */; };
|
||||
EBC05C5B2E33937200EECC18 /* ErrorAlertHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C5A2E33936C00EECC18 /* ErrorAlertHandler.swift */; };
|
||||
EBC05C5C2E3394EF00EECC18 /* ErrorAlertHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C5A2E33936C00EECC18 /* ErrorAlertHandler.swift */; };
|
||||
EBC05C712E33B57D00EECC18 /* Converter.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C6D2E33B57D00EECC18 /* Converter.swift */; };
|
||||
EBC05C722E33B57D00EECC18 /* Helper.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C6E2E33B57D00EECC18 /* Helper.swift */; };
|
||||
EBC05C732E33B57D00EECC18 /* PlusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C6F2E33B57D00EECC18 /* PlusView.swift */; };
|
||||
EBC05C782E33B58100EECC18 /* ActiveNetworkInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C742E33B58100EECC18 /* ActiveNetworkInterface.swift */; };
|
||||
EBC05C792E33B58100EECC18 /* ApIsolation6Tester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C752E33B58100EECC18 /* ApIsolation6Tester.swift */; };
|
||||
EBC05C7A2E33B58100EECC18 /* ApIsolationTester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C762E33B58100EECC18 /* ApIsolationTester.swift */; };
|
||||
EBC05C7B2E33B58100EECC18 /* ActiveNetworkInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C742E33B58100EECC18 /* ActiveNetworkInterface.swift */; };
|
||||
EBC05C7C2E33B58100EECC18 /* ApIsolationTester.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C762E33B58100EECC18 /* ApIsolationTester.swift */; };
|
||||
EBC05C822E33B58300EECC18 /* ApIsolationIssueView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C7D2E33B58300EECC18 /* ApIsolationIssueView.swift */; };
|
||||
EBC05C832E33B58300EECC18 /* FirewallIssueView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C7E2E33B58300EECC18 /* FirewallIssueView.swift */; };
|
||||
EBC05C842E33B58300EECC18 /* IssueView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EBC05C7F2E33B58300EECC18 /* IssueView.swift */; };
|
||||
@@ -303,6 +314,12 @@
|
||||
69DA9A2C29E18CB500A442DA /* securegcm.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = securegcm.pb.swift; sourceTree = "<group>"; };
|
||||
69DA9A2D29E18CB500A442DA /* securemessage.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = securemessage.pb.swift; sourceTree = "<group>"; };
|
||||
EB05DFBD2E59FC8000EF567A /* TrustedDevicesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustedDevicesView.swift; sourceTree = "<group>"; };
|
||||
EB1325D22E701D8900FD749C /* Settings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = "<group>"; };
|
||||
EB1325E72E7025D900FD749C /* ActiveNetworkInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveNetworkInterface.swift; sourceTree = "<group>"; };
|
||||
EB1325E82E7025D900FD749C /* ApIsolation6Tester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolation6Tester.swift; sourceTree = "<group>"; };
|
||||
EB1325E92E7025D900FD749C /* ApIsolationTester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolationTester.swift; sourceTree = "<group>"; };
|
||||
EB1325F72E70287C00FD749C /* SendToExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendToExtension.swift; sourceTree = "<group>"; };
|
||||
EB1325FC2E7034B000FD749C /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = "<group>"; };
|
||||
EB16B6112E58B4B9007D9792 /* IdentityManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityManager.swift; sourceTree = "<group>"; };
|
||||
EB16B6162E58B4C8007D9792 /* TrustStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrustStore.swift; sourceTree = "<group>"; };
|
||||
EB16B7762E59BA9F007D9792 /* AppGroup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppGroup.swift; sourceTree = "<group>"; };
|
||||
@@ -319,23 +336,8 @@
|
||||
EB5C383E2E38C49D0052EFD7 /* LaunchAtLogin.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchAtLogin.swift; sourceTree = "<group>"; };
|
||||
EB6F62D62D91F4AC00534EC2 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
|
||||
EB704A812E4A7BAE008E608F /* DistributionDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DistributionDetector.swift; sourceTree = "<group>"; };
|
||||
EB721F232E75AFA900F2099F /* QuickDropIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = QuickDropIcon.icon; sourceTree = "<group>"; };
|
||||
EB7654772E525ACC006B4AA3 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; };
|
||||
EB7654C22E534E89006B4AA3 /* InfoPlist.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = InfoPlist.strings; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654C82E534F2C006B4AA3 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654C92E534F2D006B4AA3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
EB7654CA2E534F31006B4AA3 /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654CB2E534F32006B4AA3 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654CC2E534F33006B4AA3 /* hu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hu; path = hu.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654CD2E534F33006B4AA3 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654CE2E534F34006B4AA3 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654CF2E534F35006B4AA3 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = ko.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654D02E534F35006B4AA3 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
EB7654D12E534F41006B4AA3 /* pt-PT */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-PT"; path = "pt-PT.lproj/InfoPlist.strings"; sourceTree = "<group>"; };
|
||||
EB7654D22E534F42006B4AA3 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654D32E534F43006B4AA3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654D42E534F43006B4AA3 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654D52E534F44006B4AA3 /* th */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = th; path = th.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7654D62E534F45006B4AA3 /* uk */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = uk; path = uk.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
EB7CD1442D6FB0C100CB0CB5 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||
EB7F54112D78E95C00989564 /* TutorialView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TutorialView.swift; sourceTree = "<group>"; };
|
||||
EB7F54132D78E9E400989564 /* LicenseWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LicenseWindow.swift; sourceTree = "<group>"; };
|
||||
@@ -364,9 +366,6 @@
|
||||
EBC05C6D2E33B57D00EECC18 /* Converter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Converter.swift; sourceTree = "<group>"; };
|
||||
EBC05C6E2E33B57D00EECC18 /* Helper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helper.swift; sourceTree = "<group>"; };
|
||||
EBC05C6F2E33B57D00EECC18 /* PlusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlusView.swift; sourceTree = "<group>"; };
|
||||
EBC05C742E33B58100EECC18 /* ActiveNetworkInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveNetworkInterface.swift; sourceTree = "<group>"; };
|
||||
EBC05C752E33B58100EECC18 /* ApIsolation6Tester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolation6Tester.swift; sourceTree = "<group>"; };
|
||||
EBC05C762E33B58100EECC18 /* ApIsolationTester.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolationTester.swift; sourceTree = "<group>"; };
|
||||
EBC05C7D2E33B58300EECC18 /* ApIsolationIssueView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApIsolationIssueView.swift; sourceTree = "<group>"; };
|
||||
EBC05C7E2E33B58300EECC18 /* FirewallIssueView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirewallIssueView.swift; sourceTree = "<group>"; };
|
||||
EBC05C7F2E33B58300EECC18 /* IssueView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IssueView.swift; sourceTree = "<group>"; };
|
||||
@@ -402,8 +401,8 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EB97A0132E51D6B2008B8C5C /* RNDeviceName in Frameworks */,
|
||||
EB5C37F02E377C3F0052EFD7 /* SwiftECC in Frameworks */,
|
||||
EBADEB8F2E8029750021B5E4 /* DeviceKit in Frameworks */,
|
||||
EB886E582E4E66420052B7D9 /* LUI in Frameworks */,
|
||||
EB5C37EE2E377C3F0052EFD7 /* SwiftProtobuf in Frameworks */,
|
||||
EB9925892E45F13500357055 /* QRCode in Frameworks */,
|
||||
@@ -414,8 +413,8 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EB950B672E520680002D68FA /* RNDeviceName in Frameworks */,
|
||||
EB950B612E520674002D68FA /* SwiftECC in Frameworks */,
|
||||
EBADEB912E802A830021B5E4 /* DeviceKit in Frameworks */,
|
||||
EB950B652E52067D002D68FA /* LUI in Frameworks */,
|
||||
EB950B5F2E520671002D68FA /* SwiftProtobuf in Frameworks */,
|
||||
EB950B632E52067A002D68FA /* QRCode in Frameworks */,
|
||||
@@ -450,6 +449,7 @@
|
||||
69DA9A0529E0BF5100A442DA = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EB721F232E75AFA900F2099F /* QuickDropIcon.icon */,
|
||||
69DA9A1029E0BF5100A442DA /* QuickDrop */,
|
||||
699DEBA22AB0573200115D22 /* ShareExtension */,
|
||||
69DCF4822AB70D0600CBE2CC /* NearbyShare */,
|
||||
@@ -476,8 +476,9 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
69DA9A1129E0BF5100A442DA /* AppDelegate.swift */,
|
||||
EB1325D22E701D8900FD749C /* Settings.swift */,
|
||||
EB1325EA2E7025D900FD749C /* SelfTest */,
|
||||
EBC05C6A2E33B55100EECC18 /* View */,
|
||||
EBC05C772E33B58100EECC18 /* SelfTest */,
|
||||
EBC05C6B2E33B57100EECC18 /* Util */,
|
||||
EBC05C702E33B57D00EECC18 /* Plus */,
|
||||
69DA9A1329E0BF5200A442DA /* Assets.xcassets */,
|
||||
@@ -511,6 +512,16 @@
|
||||
path = NearbyShare;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EB1325EA2E7025D900FD749C /* SelfTest */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EB1325E72E7025D900FD749C /* ActiveNetworkInterface.swift */,
|
||||
EB1325E82E7025D900FD749C /* ApIsolation6Tester.swift */,
|
||||
EB1325E92E7025D900FD749C /* ApIsolationTester.swift */,
|
||||
);
|
||||
path = SelfTest;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EB5C371C2E3669010052EFD7 /* Util */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -573,7 +584,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EB97A0162E51DF4F008B8C5C /* Info.plist */,
|
||||
EB7654C32E534E89006B4AA3 /* InfoPlist.strings */,
|
||||
EB1325FC2E7034B000FD749C /* InfoPlist.xcstrings */,
|
||||
EB979F8D2E50CA23008B8C5C /* Configuration.swift */,
|
||||
EB979F8E2E50CA23008B8C5C /* ContentView.swift */,
|
||||
EB979F8F2E50CA23008B8C5C /* FilePicker.swift */,
|
||||
@@ -604,6 +615,7 @@
|
||||
EBC05C6B2E33B57100EECC18 /* Util */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EB1325F72E70287C00FD749C /* SendToExtension.swift */,
|
||||
EB5C383E2E38C49D0052EFD7 /* LaunchAtLogin.swift */,
|
||||
EB886E662E4F2F7C0052B7D9 /* License.swift */,
|
||||
EB36435F2D73A29F009CDFF8 /* AudioManager.swift */,
|
||||
@@ -623,16 +635,6 @@
|
||||
path = Plus;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EBC05C772E33B58100EECC18 /* SelfTest */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EBC05C742E33B58100EECC18 /* ActiveNetworkInterface.swift */,
|
||||
EBC05C752E33B58100EECC18 /* ApIsolation6Tester.swift */,
|
||||
EBC05C762E33B58100EECC18 /* ApIsolationTester.swift */,
|
||||
);
|
||||
path = SelfTest;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EBC05C812E33B58300EECC18 /* IssueViews */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -722,7 +724,7 @@
|
||||
EB5C37EF2E377C3F0052EFD7 /* SwiftECC */,
|
||||
EB9925882E45F13500357055 /* QRCode */,
|
||||
EB886E572E4E66420052B7D9 /* LUI */,
|
||||
EB97A0122E51D6B2008B8C5C /* RNDeviceName */,
|
||||
EBADEB8E2E8029750021B5E4 /* DeviceKit */,
|
||||
);
|
||||
productName = QuickDropiOS;
|
||||
productReference = EB5C37E22E377C2E0052EFD7 /* QuickDropiOS.app */;
|
||||
@@ -746,7 +748,7 @@
|
||||
EB950B602E520674002D68FA /* SwiftECC */,
|
||||
EB950B622E52067A002D68FA /* QRCode */,
|
||||
EB950B642E52067D002D68FA /* LUI */,
|
||||
EB950B662E520680002D68FA /* RNDeviceName */,
|
||||
EBADEB902E802A830021B5E4 /* DeviceKit */,
|
||||
);
|
||||
productName = iOSShareExtension;
|
||||
productReference = EB950B2D2E52027F002D68FA /* iOSShareExtension.appex */;
|
||||
@@ -760,7 +762,7 @@
|
||||
attributes = {
|
||||
BuildIndependentTargetsInParallel = 1;
|
||||
LastSwiftUpdateCheck = 1640;
|
||||
LastUpgradeCheck = 1640;
|
||||
LastUpgradeCheck = 2600;
|
||||
TargetAttributes = {
|
||||
699DEBA02AB0573200115D22 = {
|
||||
CreatedOnToolsVersion = 14.3.1;
|
||||
@@ -808,7 +810,7 @@
|
||||
EB2F9BFC2DA05F48004010A2 /* XCRemoteSwiftPackageReference "BezelNotification" */,
|
||||
EB9925832E45EF0900357055 /* XCRemoteSwiftPackageReference "qrcode" */,
|
||||
EB886E562E4E66420052B7D9 /* XCRemoteSwiftPackageReference "LUI" */,
|
||||
EB97A0112E51D6B2008B8C5C /* XCRemoteSwiftPackageReference "RNDeviceName" */,
|
||||
EBADEB8B2E8029420021B5E4 /* XCRemoteSwiftPackageReference "DeviceKit" */,
|
||||
);
|
||||
productRefGroup = 69DA9A0F29E0BF5100A442DA /* Products */;
|
||||
projectDirPath = "";
|
||||
@@ -845,6 +847,7 @@
|
||||
EB5C36E42E34EC0E0052EFD7 /* License.txt in Resources */,
|
||||
EB5C36932E34EBBD0052EFD7 /* Localizable.xcstrings in Resources */,
|
||||
EBC05C8C2E33B59E00EECC18 /* timeIsNow.mp3 in Resources */,
|
||||
EB721F252E75AFA900F2099F /* QuickDropIcon.icon in Resources */,
|
||||
EB5C38392E38C1F60052EFD7 /* justMaybe.mp3 in Resources */,
|
||||
EB7654782E525ACC006B4AA3 /* MainMenu.xib in Resources */,
|
||||
);
|
||||
@@ -855,9 +858,10 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EB5C383B2E38C1F60052EFD7 /* justMaybe.mp3 in Resources */,
|
||||
EB7654C42E534E89006B4AA3 /* InfoPlist.strings in Resources */,
|
||||
EB1325FD2E7034B000FD749C /* InfoPlist.xcstrings in Resources */,
|
||||
EB97A0142E51DD00008B8C5C /* License.txt in Resources */,
|
||||
EB97A0152E51DD00008B8C5C /* timeIsNow.mp3 in Resources */,
|
||||
EB721F242E75AFA900F2099F /* QuickDropIcon.icon in Resources */,
|
||||
EB886E552E4E50F40052B7D9 /* Localizable.xcstrings in Resources */,
|
||||
EB7654C02E534A8E006B4AA3 /* Assets.xcassets in Resources */,
|
||||
);
|
||||
@@ -868,7 +872,7 @@
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EB950B5B2E52065A002D68FA /* timeIsNow.mp3 in Resources */,
|
||||
EB7654C62E534E89006B4AA3 /* InfoPlist.strings in Resources */,
|
||||
EB1325FE2E7034B000FD749C /* InfoPlist.xcstrings in Resources */,
|
||||
EB950B702E520734002D68FA /* Localizable.xcstrings in Resources */,
|
||||
EB950B5C2E52065A002D68FA /* justMaybe.mp3 in Resources */,
|
||||
EB950B5D2E52065A002D68FA /* License.txt in Resources */,
|
||||
@@ -885,6 +889,7 @@
|
||||
files = (
|
||||
EB704A832E4B10D4008E608F /* DistributionDetector.swift in Sources */,
|
||||
EB96ED902D7F8114004B3FF1 /* Localized.swift in Sources */,
|
||||
EB1325F82E70288300FD749C /* SendToExtension.swift in Sources */,
|
||||
EB16B6172E58B4C8007D9792 /* TrustStore.swift in Sources */,
|
||||
EB886E542E4E19390052B7D9 /* HKDF.swift in Sources */,
|
||||
EBC05C862E33B58300EECC18 /* NetworkFilterIssueView.swift in Sources */,
|
||||
@@ -901,13 +906,12 @@
|
||||
EB5C37C82E377A780052EFD7 /* ukey.pb.swift in Sources */,
|
||||
EB5C37C92E377A780052EFD7 /* device_to_device_messages.pb.swift in Sources */,
|
||||
EB950B742E520957002D68FA /* Attachments.swift in Sources */,
|
||||
EB1325D32E701D8E00FD749C /* Settings.swift in Sources */,
|
||||
EB16B7782E59BAA1007D9792 /* AppGroup.swift in Sources */,
|
||||
EB5C383C2E38C2D90052EFD7 /* AudioManager.swift in Sources */,
|
||||
EB5C37CA2E377A780052EFD7 /* offline_wire_formats.pb.swift in Sources */,
|
||||
EB16B6122E58B4B9007D9792 /* IdentityManager.swift in Sources */,
|
||||
EBC05C5C2E3394EF00EECC18 /* ErrorAlertHandler.swift in Sources */,
|
||||
EBC05C7B2E33B58100EECC18 /* ActiveNetworkInterface.swift in Sources */,
|
||||
EBC05C7C2E33B58100EECC18 /* ApIsolationTester.swift in Sources */,
|
||||
691F53BB2ABB70840089FD92 /* DeviceListCell.swift in Sources */,
|
||||
EB5C383F2E38C49D0052EFD7 /* LaunchAtLogin.swift in Sources */,
|
||||
EB5C37BC2E377A700052EFD7 /* SleepManager.swift in Sources */,
|
||||
@@ -918,6 +922,9 @@
|
||||
EB5C37D32E377A7F0052EFD7 /* InboundNearbyConnection.swift in Sources */,
|
||||
EB5C37D42E377A7F0052EFD7 /* NearbyConnectionManager.swift in Sources */,
|
||||
EB5C37BD2E377A700052EFD7 /* Helpers.swift in Sources */,
|
||||
EB1325EB2E7025D900FD749C /* ApIsolationTester.swift in Sources */,
|
||||
EB1325EC2E7025D900FD749C /* ActiveNetworkInterface.swift in Sources */,
|
||||
EB1325ED2E7025D900FD749C /* ApIsolation6Tester.swift in Sources */,
|
||||
EB5C37BE2E377A700052EFD7 /* SaveFilesManager.swift in Sources */,
|
||||
EB9925822E45D53E00357055 /* sharing_enums.pb.swift in Sources */,
|
||||
);
|
||||
@@ -936,6 +943,7 @@
|
||||
EB05DFBE2E59FC8900EF567A /* TrustedDevicesView.swift in Sources */,
|
||||
EB16B6182E58B4C8007D9792 /* TrustStore.swift in Sources */,
|
||||
EBC05C5B2E33937200EECC18 /* ErrorAlertHandler.swift in Sources */,
|
||||
EB1325D42E701D8E00FD749C /* Settings.swift in Sources */,
|
||||
EBC05C712E33B57D00EECC18 /* Converter.swift in Sources */,
|
||||
EB886E5D2E4F13EB0052B7D9 /* Zip.swift in Sources */,
|
||||
EBC05C722E33B57D00EECC18 /* Helper.swift in Sources */,
|
||||
@@ -948,15 +956,12 @@
|
||||
EB16B6152E58B4B9007D9792 /* IdentityManager.swift in Sources */,
|
||||
EB5C37C42E377A780052EFD7 /* securegcm.pb.swift in Sources */,
|
||||
EB97A0102E51CD13008B8C5C /* ReceiveModel.swift in Sources */,
|
||||
EBC05C782E33B58100EECC18 /* ActiveNetworkInterface.swift in Sources */,
|
||||
EB5C37CB2E377A7F0052EFD7 /* NearbyConnection.swift in Sources */,
|
||||
EB5C37CC2E377A7F0052EFD7 /* DataModel.swift in Sources */,
|
||||
EB5C37CD2E377A7F0052EFD7 /* OutboundNearbyConnection.swift in Sources */,
|
||||
EB5C37CE2E377A7F0052EFD7 /* InboundNearbyConnection.swift in Sources */,
|
||||
EB5C37CF2E377A7F0052EFD7 /* NearbyConnectionManager.swift in Sources */,
|
||||
EBC05C792E33B58100EECC18 /* ApIsolation6Tester.swift in Sources */,
|
||||
EB7654A12E53252D006B4AA3 /* AttachmentDetails.swift in Sources */,
|
||||
EBC05C7A2E33B58100EECC18 /* ApIsolationTester.swift in Sources */,
|
||||
EB886E522E4E19390052B7D9 /* HKDF.swift in Sources */,
|
||||
EB96ED8C2D7F7E7B004B3FF1 /* SmallSheetView.swift in Sources */,
|
||||
EB886E682E4F2F800052B7D9 /* License.swift in Sources */,
|
||||
@@ -971,6 +976,10 @@
|
||||
EB16B77A2E59BAA1007D9792 /* AppGroup.swift in Sources */,
|
||||
EBC05C822E33B58300EECC18 /* ApIsolationIssueView.swift in Sources */,
|
||||
EBC05C832E33B58300EECC18 /* FirewallIssueView.swift in Sources */,
|
||||
EB1325FA2E70288300FD749C /* SendToExtension.swift in Sources */,
|
||||
EB1325F42E7025D900FD749C /* ApIsolationTester.swift in Sources */,
|
||||
EB1325F52E7025D900FD749C /* ActiveNetworkInterface.swift in Sources */,
|
||||
EB1325F62E7025D900FD749C /* ApIsolation6Tester.swift in Sources */,
|
||||
EBC05C842E33B58300EECC18 /* IssueView.swift in Sources */,
|
||||
EBC05C852E33B58300EECC18 /* NetworkFilterIssueView.swift in Sources */,
|
||||
);
|
||||
@@ -980,6 +989,7 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
EB821C992E76FE5300036963 /* SmallSheetView.swift in Sources */,
|
||||
EB05DFBF2E59FD0A00EF567A /* TrustedDevicesView.swift in Sources */,
|
||||
EB5C37F12E377CE70052EFD7 /* ukey.pb.swift in Sources */,
|
||||
EB5C37F22E377CE70052EFD7 /* NearbyConnection.swift in Sources */,
|
||||
@@ -998,6 +1008,7 @@
|
||||
EB5C37FB2E377CE70052EFD7 /* InboundNearbyConnection.swift in Sources */,
|
||||
EB9925802E45D53E00357055 /* sharing_enums.pb.swift in Sources */,
|
||||
EB5C37FC2E377CE70052EFD7 /* OutboundNearbyConnection.swift in Sources */,
|
||||
EB1325D62E701D8E00FD749C /* Settings.swift in Sources */,
|
||||
EB5C37FD2E377CE70052EFD7 /* Logger.swift in Sources */,
|
||||
EB97A00F2E511124008B8C5C /* ReceiveModel.swift in Sources */,
|
||||
EB5C37FE2E377CE70052EFD7 /* offline_wire_formats.pb.swift in Sources */,
|
||||
@@ -1044,7 +1055,9 @@
|
||||
EB05DFC02E5A2EAA00EF567A /* TrustedDevicesView.swift in Sources */,
|
||||
EB950B542E520436002D68FA /* HKDF.swift in Sources */,
|
||||
EB950B552E520436002D68FA /* SaveFilesManager.swift in Sources */,
|
||||
EB1325D52E701D8E00FD749C /* Settings.swift in Sources */,
|
||||
EB950B562E520436002D68FA /* DataModel.swift in Sources */,
|
||||
EB821C9A2E76FE5300036963 /* SmallSheetView.swift in Sources */,
|
||||
EB950B3E2E52038A002D68FA /* SendModel.swift in Sources */,
|
||||
EB950B772E521712002D68FA /* AttachmentDetails.swift in Sources */,
|
||||
EB16B6192E58B4C8007D9792 /* TrustStore.swift in Sources */,
|
||||
@@ -1085,29 +1098,6 @@
|
||||
name = ShareViewController.xib;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
EB7654C32E534E89006B4AA3 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
EB7654C22E534E89006B4AA3 /* InfoPlist.strings */,
|
||||
EB7654C82E534F2C006B4AA3 /* ar */,
|
||||
EB7654C92E534F2D006B4AA3 /* zh-Hans */,
|
||||
EB7654CA2E534F31006B4AA3 /* nl */,
|
||||
EB7654CB2E534F32006B4AA3 /* fr */,
|
||||
EB7654CC2E534F33006B4AA3 /* hu */,
|
||||
EB7654CD2E534F33006B4AA3 /* it */,
|
||||
EB7654CE2E534F34006B4AA3 /* ja */,
|
||||
EB7654CF2E534F35006B4AA3 /* ko */,
|
||||
EB7654D02E534F35006B4AA3 /* pt-BR */,
|
||||
EB7654D12E534F41006B4AA3 /* pt-PT */,
|
||||
EB7654D22E534F42006B4AA3 /* ro */,
|
||||
EB7654D32E534F43006B4AA3 /* ru */,
|
||||
EB7654D42E534F43006B4AA3 /* es */,
|
||||
EB7654D52E534F44006B4AA3 /* th */,
|
||||
EB7654D62E534F45006B4AA3 /* uk */,
|
||||
);
|
||||
name = InfoPlist.strings;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
@@ -1121,7 +1111,11 @@
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = "${SHARED_BUILD}";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_USER_SELECTED_FILES = readonly;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = QuickDrop;
|
||||
@@ -1155,7 +1149,11 @@
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = "${SHARED_BUILD}";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_USER_SELECTED_FILES = readonly;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = ShareExtension/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = QuickDrop;
|
||||
@@ -1241,8 +1239,9 @@
|
||||
MTL_FAST_MATH = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = macosx;
|
||||
SHARED_BUILD = 68;
|
||||
SHARED_VERSION = 2.2.1;
|
||||
SHARED_BUILD = 74;
|
||||
SHARED_VERSION = 2.4.1;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
@@ -1303,8 +1302,9 @@
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
MTL_FAST_MATH = YES;
|
||||
SDKROOT = macosx;
|
||||
SHARED_BUILD = 68;
|
||||
SHARED_VERSION = 2.2.1;
|
||||
SHARED_BUILD = 74;
|
||||
SHARED_VERSION = 2.4.1;
|
||||
STRING_CATALOG_GENERATE_SYMBOLS = YES;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-O";
|
||||
@@ -1314,7 +1314,7 @@
|
||||
69DA9A1C29E0BF5200A442DA /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = QuickDropIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = QuickDrop/QuickDrop.entitlements;
|
||||
@@ -1324,7 +1324,12 @@
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = "${SHARED_BUILD}";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
ENABLE_FILE_ACCESS_DOWNLOADS_FOLDER = readwrite;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_USER_SELECTED_FILES = readwrite;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = QuickDrop/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = QuickDrop;
|
||||
@@ -1355,7 +1360,7 @@
|
||||
69DA9A1D29E0BF5200A442DA /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = QuickDropIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = QuickDrop/QuickDrop.entitlements;
|
||||
@@ -1365,7 +1370,12 @@
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = "${SHARED_BUILD}";
|
||||
DEAD_CODE_STRIPPING = YES;
|
||||
ENABLE_APP_SANDBOX = YES;
|
||||
ENABLE_FILE_ACCESS_DOWNLOADS_FOLDER = readwrite;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
ENABLE_INCOMING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;
|
||||
ENABLE_USER_SELECTED_FILES = readwrite;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = QuickDrop/Info.plist;
|
||||
INFOPLIST_KEY_CFBundleDisplayName = QuickDrop;
|
||||
@@ -1395,7 +1405,7 @@
|
||||
EB5C37EB2E377C310052EFD7 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = QuickDropIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = QuickDropiOS/QuickDropiOS.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -1408,6 +1418,7 @@
|
||||
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Leon Böttger";
|
||||
INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Local network access is needed to detect devices and transfer files over your Wi-Fi network.";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
@@ -1438,7 +1449,7 @@
|
||||
EB5C37EC2E377C310052EFD7 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = QuickDropIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CODE_SIGN_ENTITLEMENTS = QuickDropiOS/QuickDropiOS.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
@@ -1451,6 +1462,7 @@
|
||||
INFOPLIST_KEY_ITSAppUsesNonExemptEncryption = NO;
|
||||
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
|
||||
INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
|
||||
INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2025 Leon Böttger";
|
||||
INFOPLIST_KEY_NSLocalNetworkUsageDescription = "Local network access is needed to detect devices and transfer files over your Wi-Fi network.";
|
||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||
@@ -1622,14 +1634,6 @@
|
||||
kind = branch;
|
||||
};
|
||||
};
|
||||
EB97A0112E51D6B2008B8C5C /* XCRemoteSwiftPackageReference "RNDeviceName" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/souzainf3/RNDeviceName";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 2.1.0;
|
||||
};
|
||||
};
|
||||
EB9925832E45EF0900357055 /* XCRemoteSwiftPackageReference "qrcode" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/dagronf/qrcode.git";
|
||||
@@ -1638,6 +1642,14 @@
|
||||
minimumVersion = 26.10.0;
|
||||
};
|
||||
};
|
||||
EBADEB8B2E8029420021B5E4 /* XCRemoteSwiftPackageReference "DeviceKit" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/devicekit/DeviceKit";
|
||||
requirement = {
|
||||
kind = upToNextMajorVersion;
|
||||
minimumVersion = 5.7.0;
|
||||
};
|
||||
};
|
||||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
@@ -1701,16 +1713,6 @@
|
||||
package = EB886E562E4E66420052B7D9 /* XCRemoteSwiftPackageReference "LUI" */;
|
||||
productName = LUI;
|
||||
};
|
||||
EB950B662E520680002D68FA /* RNDeviceName */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = EB97A0112E51D6B2008B8C5C /* XCRemoteSwiftPackageReference "RNDeviceName" */;
|
||||
productName = RNDeviceName;
|
||||
};
|
||||
EB97A0122E51D6B2008B8C5C /* RNDeviceName */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = EB97A0112E51D6B2008B8C5C /* XCRemoteSwiftPackageReference "RNDeviceName" */;
|
||||
productName = RNDeviceName;
|
||||
};
|
||||
EB9925842E45EF0900357055 /* QRCode */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = EB9925832E45EF0900357055 /* XCRemoteSwiftPackageReference "qrcode" */;
|
||||
@@ -1726,6 +1728,16 @@
|
||||
package = EB9925832E45EF0900357055 /* XCRemoteSwiftPackageReference "qrcode" */;
|
||||
productName = QRCode;
|
||||
};
|
||||
EBADEB8E2E8029750021B5E4 /* DeviceKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = EBADEB8B2E8029420021B5E4 /* XCRemoteSwiftPackageReference "DeviceKit" */;
|
||||
productName = DeviceKit;
|
||||
};
|
||||
EBADEB902E802A830021B5E4 /* DeviceKit */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = EBADEB8B2E8029420021B5E4 /* XCRemoteSwiftPackageReference "DeviceKit" */;
|
||||
productName = DeviceKit;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
};
|
||||
rootObject = 69DA9A0629E0BF5100A442DA /* Project object */;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"originHash" : "212cf044c2b0bab89578ca93a3666a656e0c44fb54a69f813c4cc4fae07827d7",
|
||||
"originHash" : "270e8bfd245fae589b12faf08b86042cbbe7c809d59c5b0b8b735c7fb3a8d4bd",
|
||||
"pins" : [
|
||||
{
|
||||
"identity" : "applewatchscreensize",
|
||||
@@ -37,13 +37,22 @@
|
||||
"version" : "1.21.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "devicekit",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/devicekit/DeviceKit",
|
||||
"state" : {
|
||||
"revision" : "581df61650bc457ec00373a592a84be3e7468eb1",
|
||||
"version" : "5.7.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "lui",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/leonboe1/LUI.git",
|
||||
"state" : {
|
||||
"branch" : "main",
|
||||
"revision" : "5b2fe7161069c2314c5be17810ec7471b9decc8a"
|
||||
"revision" : "123192312165c23271cd49492ae7e4fc676d7711"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -55,15 +64,6 @@
|
||||
"version" : "26.10.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "rndevicename",
|
||||
"kind" : "remoteSourceControl",
|
||||
"location" : "https://github.com/souzainf3/RNDeviceName",
|
||||
"state" : {
|
||||
"revision" : "68ada02a7135381425b01778aeb8719ce3bf8f62",
|
||||
"version" : "2.1.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"identity" : "swift-cross-kit-types",
|
||||
"kind" : "remoteSourceControl",
|
||||
@@ -124,7 +124,7 @@
|
||||
"location" : "https://github.com/siteline/swiftui-introspect",
|
||||
"state" : {
|
||||
"branch" : "main",
|
||||
"revision" : "9bedf1e79c7b7c34b35b74bef126f56d2400ef7f"
|
||||
"revision" : "d620dacd1423d9545635eee3fc42c1fa1ab2f665"
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1640"
|
||||
LastUpgradeVersion = "2600"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1640"
|
||||
LastUpgradeVersion = "2600"
|
||||
version = "1.7">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
@@ -32,8 +32,8 @@
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
selectedDebuggerIdentifier = ""
|
||||
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1640"
|
||||
LastUpgradeVersion = "2600"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1640"
|
||||
LastUpgradeVersion = "2600"
|
||||
wasCreatedForAppExtension = "YES"
|
||||
version = "2.0">
|
||||
<BuildAction
|
||||
|
||||
@@ -38,14 +38,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
let menu = NSMenu()
|
||||
|
||||
let visibleItem = NSMenuItem(
|
||||
title: "VisibleToEveryone".localized(),
|
||||
title: getDefaultVisibleLabel(),
|
||||
action: nil,
|
||||
keyEquivalent: ""
|
||||
)
|
||||
self.visibleItem = visibleItem
|
||||
menu.addItem(visibleItem)
|
||||
|
||||
menu.addItem(withTitle: String(format: "DeviceName".localized(), arguments: [Host.current().localizedName ?? "Mac"]), action: nil, keyEquivalent: "")
|
||||
|
||||
menu.addItem(NSMenuItem.separator())
|
||||
|
||||
@@ -70,23 +68,23 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
log("[AppDelegate] Downloaded directly: \(DistributionDetector.isDirectDistributionEnabled)")
|
||||
|
||||
// app did not lauch before
|
||||
if !UserDefaults.standard.bool(forKey: UserDefaultsKeys.appLaunchedBefore.rawValue) {
|
||||
if !Settings.shared.appLaunchedBefore {
|
||||
log("[AppDelegate] Opening Welcome Screen")
|
||||
// open welcome screen
|
||||
openWelcomeScreen()
|
||||
UserDefaults.standard.set(true, forKey: UserDefaultsKeys.appLaunchedBefore.rawValue)
|
||||
Settings.shared.appLaunchedBefore = true
|
||||
|
||||
// user installed the app after the IAP was implemented, set the user as eligible for IAP
|
||||
UserDefaults.standard.set(true, forKey: UserDefaultsKeys.isEligibleForIap.rawValue)
|
||||
Settings.shared.isEligibleForIap = true
|
||||
} else {
|
||||
// app launched before
|
||||
|
||||
// user installed the app before the IAP was implemented, grant the plus version
|
||||
if !UserDefaults.standard.bool(forKey: UserDefaultsKeys.isEligibleForIap.rawValue) {
|
||||
if !Settings.shared.isEligibleForIap {
|
||||
log("[AppDelegate] Granting QuickDrop+ for old user")
|
||||
UserDefaults.standard.set(true, forKey: UserDefaultsKeys.plusVersion.rawValue)
|
||||
Settings.shared.gotPlus = true
|
||||
} else {
|
||||
if !isPlusVersion() {
|
||||
if !fullVersion() {
|
||||
log("[AppDelegate] New user - QuickDrop+ not available")
|
||||
}
|
||||
else {
|
||||
@@ -116,7 +114,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
NearbyConnectionManager.shared.connectionUpdateCallback = { isConnected in
|
||||
if isConnected {
|
||||
self.statusItem?.button?.image = NSImage(named: "MenuBarIcon")
|
||||
self.visibleItem?.title = "VisibleToEveryone".localized()
|
||||
self.visibleItem?.title = self.getDefaultVisibleLabel()
|
||||
}
|
||||
else {
|
||||
self.statusItem?.button?.image = NSImage(named: "MenuBarIconSlash")
|
||||
@@ -124,7 +122,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
}
|
||||
}
|
||||
|
||||
log("Application did finish launching")
|
||||
log("[AppDelegate] Application did finish launching")
|
||||
}
|
||||
|
||||
|
||||
@@ -191,8 +189,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
}
|
||||
}
|
||||
else {
|
||||
let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension"))
|
||||
sharingService?.perform(withItems: [clipboardString])
|
||||
sendToSharingService(items: [clipboardString])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,6 +335,12 @@ class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCenterDele
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private func getDefaultVisibleLabel() -> String {
|
||||
let name = NearbyConnectionManager.shared.deviceInfo.name ?? "Unknown".localized()
|
||||
return String(format: "VisibleAs".localized(), name)
|
||||
}
|
||||
}
|
||||
|
||||
struct TransferInfo {
|
||||
|
||||
|
After Width: | Height: | Size: 585 KiB |
|
Before Width: | Height: | Size: 1016 KiB |
|
Before Width: | Height: | Size: 752 KiB After Width: | Height: | Size: 672 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "1024-1024 1.png",
|
||||
"filename" : "1024-1024 1 2.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
|
||||
|
Before Width: | Height: | Size: 752 KiB After Width: | Height: | Size: 672 KiB |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "FileTransfer Kopie-1024.png",
|
||||
"filename" : "FileTransfer Kopie-512.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
|
||||
|
Before Width: | Height: | Size: 647 KiB |
|
After Width: | Height: | Size: 111 KiB |
@@ -15,5 +15,7 @@
|
||||
</array>
|
||||
</dict>
|
||||
</array>
|
||||
<key>UIDesignRequiresCompatibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -13,7 +13,7 @@ let plusViewHeight: CGFloat = 200
|
||||
|
||||
struct PlusView: View {
|
||||
|
||||
@AppStorage(UserDefaultsKeys.plusVersion.rawValue) var isPlusVersion = false
|
||||
@ObservedObject private var settings = Settings.shared
|
||||
@ObservedObject private var iaphelper = IAPManager.sharedInstance
|
||||
let closeView: () -> Void
|
||||
|
||||
@@ -115,7 +115,7 @@ struct PlusView: View {
|
||||
if success {
|
||||
log("[LUI] Restored purchases successfully")
|
||||
withAnimation {
|
||||
isPlusVersion = true
|
||||
settings.gotPlus = true
|
||||
}
|
||||
boughtSuccessAlert = true
|
||||
} else {
|
||||
@@ -146,7 +146,7 @@ struct PlusView: View {
|
||||
|
||||
if success {
|
||||
withAnimation {
|
||||
isPlusVersion = true
|
||||
settings.gotPlus = true
|
||||
}
|
||||
|
||||
boughtSuccessAlert = true
|
||||
@@ -193,7 +193,7 @@ struct PlusView: View {
|
||||
case .success(_):
|
||||
|
||||
withAnimation {
|
||||
isPlusVersion = true
|
||||
settings.gotPlus = true
|
||||
boughtSuccessAlert = true
|
||||
warning = false
|
||||
}
|
||||
|
||||
@@ -2,19 +2,9 @@
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.application-groups</key>
|
||||
<array>
|
||||
<string>group.com.leonboettger.neardrop</string>
|
||||
</array>
|
||||
<key>com.apple.security.files.downloads.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.server</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1,79 @@
|
||||
//
|
||||
// Settings.swift
|
||||
// QuickDrop
|
||||
//
|
||||
// Created by Leon Böttger on 09.09.25.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
class Settings: ObservableObject {
|
||||
|
||||
private init() {}
|
||||
|
||||
static var shared = Settings()
|
||||
|
||||
|
||||
// MARK: - Published UserDefaults Backed Properties
|
||||
|
||||
@Published var gotPlus = UserDefaults.standard.bool(forKey: UserDefaultsKeys.plusVersion.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(gotPlus, forKey: UserDefaultsKeys.plusVersion.rawValue) }}
|
||||
|
||||
|
||||
@Published var automaticallyAcceptFiles: Bool = UserDefaults.standard.bool(forKey: UserDefaultsKeys.automaticallyAcceptFiles.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(automaticallyAcceptFiles, forKey: UserDefaultsKeys.automaticallyAcceptFiles.rawValue) }}
|
||||
|
||||
|
||||
@Published var openFinderAfterReceiving: Bool = UserDefaults.standard.bool(forKey: UserDefaultsKeys.openFinderAfterReceiving.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(openFinderAfterReceiving, forKey: UserDefaultsKeys.openFinderAfterReceiving.rawValue) }}
|
||||
|
||||
|
||||
@Published var saveFolderBookmark: Data? = UserDefaults.standard.data(forKey: UserDefaultsKeys.saveFolderBookmark.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(saveFolderBookmark, forKey: UserDefaultsKeys.saveFolderBookmark.rawValue) }}
|
||||
|
||||
|
||||
|
||||
// MARK: - Non-Published UserDefaults Backed Properties
|
||||
|
||||
var incomingTransmissionCount: Int = UserDefaults.standard.integer(forKey: UserDefaultsKeys.transmissionCount.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(incomingTransmissionCount, forKey: UserDefaultsKeys.transmissionCount.rawValue) }}
|
||||
|
||||
|
||||
var endpointID: String? = UserDefaults.standard.string(forKey: UserDefaultsKeys.endpointID.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(endpointID, forKey: UserDefaultsKeys.endpointID.rawValue) }}
|
||||
|
||||
|
||||
var isEligibleForIap: Bool = UserDefaults.standard.bool(forKey: UserDefaultsKeys.isEligibleForIap.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(isEligibleForIap, forKey: UserDefaultsKeys.isEligibleForIap.rawValue) }}
|
||||
|
||||
|
||||
var appLaunchedBefore: Bool = UserDefaults.standard.bool(forKey: UserDefaultsKeys.appLaunchedBefore.rawValue)
|
||||
{ didSet { UserDefaults.standard.set(appLaunchedBefore, forKey: UserDefaultsKeys.appLaunchedBefore.rawValue) }}
|
||||
|
||||
|
||||
|
||||
// MARK: - Debug
|
||||
|
||||
func deleteAllUserDefaults() {
|
||||
for key in UserDefaultsKeys.allCases {
|
||||
UserDefaults.standard.removeObject(forKey: key.rawValue)
|
||||
}
|
||||
|
||||
Settings.shared = Settings()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// MARK: - UserDefaults Keys
|
||||
|
||||
public enum UserDefaultsKeys: String, CaseIterable {
|
||||
case isEligibleForIap = "isEligibleForIap"
|
||||
case appLaunchedBefore = "ShowedWelcomeScreen"
|
||||
case plusVersion = "isPlusVersion"
|
||||
case transmissionCount = "reviewRequestCountKey"
|
||||
case automaticallyAcceptFiles = "automaticallyAcceptFiles"
|
||||
case saveFolderBookmark = "saveFolderBookmark"
|
||||
case openFinderAfterReceiving = "openFinderAfterReceiving"
|
||||
case endpointID = "endpointID"
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ class ErrorAlertHandler {
|
||||
|
||||
let title = String(format: "TransferError".localized(), arguments: [deviceName])
|
||||
log("Showing alert with title: \"\(title)\" and description: \"\(description)\"")
|
||||
log("Unsuccessful transmission. Already successful transmissions: \(incomingTransmissionCount())")
|
||||
log("Unsuccessful transmission. Already successful transmissions: \(Settings.shared.incomingTransmissionCount)")
|
||||
|
||||
#if os(macOS)
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// SendToExtension.swift
|
||||
// QuickDrop
|
||||
//
|
||||
// Created by Leon Böttger on 09.09.25.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import AppKit
|
||||
|
||||
func sendToSharingService(items: [Any]) {
|
||||
if let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) {
|
||||
sharingService.perform(withItems: items)
|
||||
}
|
||||
else {
|
||||
DispatchQueue.main.async {
|
||||
// show alert
|
||||
AudioManager.playErrorSound()
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .critical
|
||||
alert.messageText = "ShareExtensionDisabledTitle".localized()
|
||||
alert.informativeText = "ShareExtensionDisabledDescription".localized()
|
||||
alert.addButton(withTitle: "CloseAlert".localized())
|
||||
alert.runModal()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,15 +10,13 @@ import AppKit
|
||||
|
||||
struct SettingsView: View {
|
||||
|
||||
@AppStorage(UserDefaultsKeys.automaticallyAcceptFiles.rawValue) private var automaticallyAcceptFiles = false
|
||||
@AppStorage(UserDefaultsKeys.openFinderAfterReceiving.rawValue) private var openFinderAfterReceiving = false
|
||||
@AppStorage(UserDefaultsKeys.saveFolderBookmark.rawValue) private var saveFolderPath: Data = Data()
|
||||
@ObservedObject var settings = Settings.shared
|
||||
|
||||
var body: some View {
|
||||
|
||||
LargeAppIconView(title: "Settings") {
|
||||
Form {
|
||||
Toggle("AutomaticallyAcceptFiles", isOn: $automaticallyAcceptFiles)
|
||||
Toggle("AutomaticallyAcceptFiles", isOn: $settings.automaticallyAcceptFiles)
|
||||
.padding(.top, 10)
|
||||
|
||||
Text("AutomaticallyAcceptFilesFooter")
|
||||
@@ -33,7 +31,7 @@ struct SettingsView: View {
|
||||
Text("SaveFilesTo")
|
||||
Spacer()
|
||||
Text(getSavedFolderPath() ?? "DownloadsFolder".localized())
|
||||
.foregroundColor(saveFolderPath.isEmpty ? .gray : .primary)
|
||||
.foregroundColor((settings.saveFolderBookmark ?? Data()).isEmpty ? .gray : .primary)
|
||||
Button("SaveFilesToButton") {
|
||||
selectFolder()
|
||||
}
|
||||
@@ -42,7 +40,7 @@ struct SettingsView: View {
|
||||
Divider()
|
||||
.padding(.vertical, 10)
|
||||
|
||||
Toggle("OpenFinderAfterReceiving", isOn: $openFinderAfterReceiving)
|
||||
Toggle("OpenFinderAfterReceiving", isOn: $settings.openFinderAfterReceiving)
|
||||
.padding(.top, 5)
|
||||
|
||||
if #available(macOS 13.0, *) {
|
||||
@@ -72,10 +70,10 @@ struct SettingsView: View {
|
||||
|
||||
|
||||
private func getSavedFolderPath() -> String? {
|
||||
if !saveFolderPath.isEmpty {
|
||||
if let bookmark = settings.saveFolderBookmark, !bookmark.isEmpty {
|
||||
var isStale = false
|
||||
do {
|
||||
let url = try URL(resolvingBookmarkData: saveFolderPath, options: [], relativeTo: nil, bookmarkDataIsStale: &isStale)
|
||||
let url = try URL(resolvingBookmarkData: bookmark, options: [], relativeTo: nil, bookmarkDataIsStale: &isStale)
|
||||
return url.lastPathComponent // Returns the folder path as a string
|
||||
} catch {
|
||||
log("Failed to resolve bookmark: \(error)")
|
||||
@@ -96,11 +94,30 @@ struct SettingsView: View {
|
||||
do {
|
||||
log("Selected folder: \(url)")
|
||||
|
||||
if url.description == "file:///" {
|
||||
throw NSError(domain: "InvalidSelection", code: 0, userInfo: [NSLocalizedDescriptionKey: "Cannot select root directory. Please choose a specific folder."])
|
||||
}
|
||||
|
||||
let bookmarkData = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
|
||||
|
||||
UserDefaults.standard.set(bookmarkData, forKey: UserDefaultsKeys.saveFolderBookmark.rawValue)
|
||||
Settings.shared.saveFolderBookmark = bookmarkData
|
||||
Settings.shared.openFinderAfterReceiving = true
|
||||
} catch {
|
||||
log("Failed to save security-scoped bookmark: \(error)")
|
||||
|
||||
DispatchQueue.main.asyncAfter(deadline: .now()) {
|
||||
|
||||
AudioManager.playErrorSound()
|
||||
|
||||
// show alert
|
||||
let alert = NSAlert()
|
||||
alert.alertStyle = .critical
|
||||
alert.messageText = "FolderSelectionFailedTitle".localized()
|
||||
alert.informativeText = "FolderSelectionFailedMessage".localized()
|
||||
alert.addButton(withTitle: "CloseAlert".localized())
|
||||
|
||||
alert.runModal()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ struct TutorialView: View {
|
||||
let openPlus: () -> Void
|
||||
|
||||
@State private var licenseWindow: NSWindow?
|
||||
@AppStorage(UserDefaultsKeys.plusVersion.rawValue) var isPlusVersion = false
|
||||
@ObservedObject var settings = Settings.shared
|
||||
|
||||
var body: some View {
|
||||
|
||||
@@ -40,7 +40,7 @@ struct TutorialView: View {
|
||||
}
|
||||
.buttonStyle(.plain)
|
||||
|
||||
if !isPlusVersion {
|
||||
if !settings.gotPlus {
|
||||
Button {
|
||||
openPlus()
|
||||
} label: {
|
||||
@@ -54,11 +54,9 @@ struct TutorialView: View {
|
||||
|
||||
#if DEBUG
|
||||
Button {
|
||||
for key in UserDefaultsKeys.allCases {
|
||||
UserDefaults.standard.removeObject(forKey: key.rawValue)
|
||||
}
|
||||
Settings.shared.deleteAllUserDefaults()
|
||||
} label: {
|
||||
Text("Reset UD")
|
||||
Text("ResetAllSettings")
|
||||
.underline()
|
||||
.font(.footnote)
|
||||
.opacity(0.5)
|
||||
|
||||
@@ -138,12 +138,6 @@ struct WelcomeScreen: View {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func sendToSharingService(items: [Any]) {
|
||||
if let sharingService = NSSharingService(named: NSSharingService.Name("com.leonboettger.neardrop.ShareExtension")) {
|
||||
sharingService.perform(withItems: items)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 52 KiB |
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"fill" : {
|
||||
"linear-gradient" : [
|
||||
"display-p3:0.31273,0.68878,0.97563,1.00000",
|
||||
"display-p3:0.22962,0.42793,0.95758,1.00000"
|
||||
]
|
||||
},
|
||||
"groups" : [
|
||||
{
|
||||
"layers" : [
|
||||
{
|
||||
"image-name" : "QuickDropArrows.png",
|
||||
"name" : "QuickDropArrows"
|
||||
},
|
||||
{
|
||||
"image-name" : "QuickDropCircle.png",
|
||||
"name" : "QuickDropCircle",
|
||||
"opacity" : 0.5
|
||||
}
|
||||
],
|
||||
"shadow" : {
|
||||
"kind" : "neutral",
|
||||
"opacity" : 0.5
|
||||
},
|
||||
"translucency" : {
|
||||
"enabled" : true,
|
||||
"value" : 0.52
|
||||
}
|
||||
}
|
||||
],
|
||||
"supported-platforms" : {
|
||||
"circles" : [
|
||||
"watchOS"
|
||||
],
|
||||
"squares" : "shared"
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,10 @@ import LUI
|
||||
let configuration = LUIConfiguration(
|
||||
appName: "QuickDrop",
|
||||
|
||||
inAppPurchaseName: "plusversion",
|
||||
|
||||
plusVersionInfo: GetPlusViewInformation(description: "plusview_description_phone", plusVersionFeatures: [], settingsLabelColor: .orange, settingsFooter: "plusview_footer_phone"),
|
||||
|
||||
hasRoundedFont: false,
|
||||
|
||||
copyrightInformation: licenseText,
|
||||
@@ -24,6 +28,8 @@ let configuration = LUIConfiguration(
|
||||
|
||||
supportsSplitView: false,
|
||||
|
||||
supportsLiquidGlass: true,
|
||||
|
||||
supportsPortraitSplitView: false,
|
||||
|
||||
supportsDarkModeShadow: false
|
||||
|
||||
@@ -12,13 +12,14 @@ import StoreKit
|
||||
struct ContentView: View {
|
||||
|
||||
@ObservedObject var luiSettings = LUISettings.sharedInstance
|
||||
@ObservedObject var settings = Settings.shared
|
||||
|
||||
var body: some View {
|
||||
AppRootView(isPlus: .constant(true), phoneView: {
|
||||
AppRootView(isPlus: $settings.gotPlus, phoneView: {
|
||||
DeviceListView()
|
||||
.environment(\.sheetActive, isShareExtension())
|
||||
}, settingsView: {
|
||||
CustomSection {
|
||||
CustomSection(header: settings.gotPlus ? "" : "General", footer: "TrustedDevicesFooterShort") {
|
||||
LUIButton {
|
||||
SaveFilesManager.shared.openDownloadedFilesFolder()
|
||||
} label: {
|
||||
@@ -37,6 +38,7 @@ struct ContentView: View {
|
||||
|
||||
struct DeviceListView: View {
|
||||
|
||||
@State private var qrCode: Image? = nil
|
||||
@StateObject var sendModel = SendModel()
|
||||
|
||||
#if !EXTENSION
|
||||
@@ -44,12 +46,15 @@ struct DeviceListView: View {
|
||||
#endif
|
||||
|
||||
@Environment(\.scenePhase) var scenePhase
|
||||
@AppStorage("requestedReview") private var requestedReview = false
|
||||
@Environment(\.sheetActive) var sheetActive
|
||||
@ObservedObject var nearbyConnectionManager = NearbyConnectionManager.shared
|
||||
@ObservedObject var settings = Settings.shared
|
||||
|
||||
var body: some View {
|
||||
|
||||
NavigationSubView(header: "QuickDrop ", navigationBarLayout: isShareExtension() ? .SmallOnlyAlways : .Default) {
|
||||
let showsLoadingIndicator = nearbyConnectionManager.hasLocalNetworkPermission && nearbyConnectionManager.isConnectedToLocalNetwork
|
||||
|
||||
BottomBarView(header: "QuickDrop ", navigationBarLayout: isShareExtension() ? .SmallOnlyAlways : .Default, bottomViewHeight: 30) {
|
||||
VStack {
|
||||
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
@@ -72,14 +77,14 @@ struct DeviceListView: View {
|
||||
}
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.vertical, 6)
|
||||
.background(Color.defaultForegroundColor)
|
||||
.background(sheetActive ? Color.sheetForegroundColor : Color.defaultForegroundColor)
|
||||
.cornerRadius(24)
|
||||
}
|
||||
.padding(.horizontal)
|
||||
.padding(.top, 8)
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
|
||||
if !nearbyConnectionManager.hasLocalNetworkAccess {
|
||||
if !nearbyConnectionManager.hasLocalNetworkPermission {
|
||||
CardView(backgroundColor: .red, title: "NoNetworkAccess", titleSymbol: "network.slash") {
|
||||
CardSubView(symbol: "exclamationmark.triangle.fill", text: "NoLocalNetworkAccessDescription")
|
||||
}
|
||||
@@ -93,16 +98,22 @@ struct DeviceListView: View {
|
||||
|
||||
CustomSection(header: "NoDevicesFound") {
|
||||
|
||||
let hasWifi = nearbyConnectionManager.isConnectedViaWiFi
|
||||
let hasWifi = nearbyConnectionManager.isConnectedToLocalNetwork
|
||||
|
||||
HStack(spacing: 12) {
|
||||
Image(systemName: hasWifi ? "arrow.down.circle.fill" : "wifi.slash")
|
||||
.font(.system(size: 30))
|
||||
.foregroundColor(.blue)
|
||||
.padding(.leading, -10)
|
||||
.frame(width: 30)
|
||||
.background(
|
||||
Circle()
|
||||
.fill(Color.white)
|
||||
.padding(3)
|
||||
.opacity(hasWifi ? 1 : 0)
|
||||
)
|
||||
.frame(width: 32)
|
||||
|
||||
Text(hasWifi ? "DownloadQuickDropOnPlayStore" : "NoWiFiConnectionDescription")
|
||||
LUIText(hasWifi ? "DownloadQuickDropOnPlayStore" : "NoWiFiConnectionDescription")
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
.animation(.default, value: hasWifi)
|
||||
.padding(.vertical)
|
||||
@@ -119,9 +130,7 @@ struct DeviceListView: View {
|
||||
if let attachments = NearbyConnectionManager.shared.attachments {
|
||||
LUIButton {
|
||||
lightVibration()
|
||||
sendModel.urls = attachments.urls
|
||||
sendModel.textToSend = attachments.textToSend
|
||||
sendModel.selectDevice(device: device)
|
||||
sendModel.selectDevice(device: device, with: attachments)
|
||||
} label: {
|
||||
DeviceButtonLabel(device: device, isSelected: isSelected, progress: sendModel.progressState, progressValue: sendModel.progressValue)
|
||||
}
|
||||
@@ -137,7 +146,7 @@ struct DeviceListView: View {
|
||||
}
|
||||
|
||||
|
||||
if nearbyConnectionManager.hasLocalNetworkAccess && nearbyConnectionManager.isConnectedViaWiFi {
|
||||
if showsLoadingIndicator {
|
||||
HStack(spacing: 8) {
|
||||
Text("SearchingForDevices")
|
||||
.font(.system(size: 14))
|
||||
@@ -151,28 +160,37 @@ struct DeviceListView: View {
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: 700)
|
||||
} bottomView: {
|
||||
|
||||
LUIButton {
|
||||
qrCode = NearbyConnectionManager.shared.generateQrCodeKey()
|
||||
sendModel.showQrCodeView = true
|
||||
} label: {
|
||||
UnderlineText(label: "DeviceNotShown")
|
||||
.padding()
|
||||
}
|
||||
.opacity(showsLoadingIndicator ? 1 : 0)
|
||||
}
|
||||
.luiSheet(isPresented: $sendModel.showQrCodeView, content: {
|
||||
NavigationView {
|
||||
NavigationSubView(header: "ConnectDevice", navigationBarLayout: .SmallOnlyAlways) {
|
||||
SmallSheetView(type: .sendToDeviceQrCode, dynamicQrCode: qrCode, closeView: {})
|
||||
}
|
||||
.navigationBarItems(trailing: XButton(action: { sendModel.showQrCodeView = false }))
|
||||
}
|
||||
})
|
||||
.onChange(of: scenePhase) { newValue in
|
||||
|
||||
if newValue == .active {
|
||||
|
||||
log("App became active")
|
||||
log("[ScenePhase] App became active")
|
||||
NearbyConnectionManager.shared.startDeviceDiscovery()
|
||||
#if !EXTENSION
|
||||
NearbyConnectionManager.shared.becomeVisible()
|
||||
|
||||
if incomingTransmissionCount() > 0 && !requestedReview {
|
||||
if Settings.shared.incomingTransmissionCount > 0 {
|
||||
runAfter(seconds: 0.3) {
|
||||
if let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene {
|
||||
|
||||
log("Requesting Review...")
|
||||
|
||||
SKStoreReviewController.requestReview(in: scene)
|
||||
requestedReview = true
|
||||
}
|
||||
else {
|
||||
log("Error Requesting Review!")
|
||||
}
|
||||
requestReviewOnce()
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -180,14 +198,15 @@ struct DeviceListView: View {
|
||||
|
||||
if newValue == .background {
|
||||
|
||||
log("App went to background")
|
||||
log("[ScenePhase] App went to background")
|
||||
#if !EXTENSION
|
||||
NearbyConnectionManager.shared.becomeInvisible()
|
||||
#endif
|
||||
NearbyConnectionManager.shared.stopDeviceDiscovery()
|
||||
}
|
||||
}
|
||||
.animation(.smooth, value: nearbyConnectionManager.hasLocalNetworkAccess)
|
||||
.animation(.smooth, value: nearbyConnectionManager.hasLocalNetworkPermission)
|
||||
.animation(.smooth, value: nearbyConnectionManager.isConnectedToLocalNetwork)
|
||||
.navigationBarItems(trailing: ZStack {
|
||||
if isShareExtension() {
|
||||
XButton(action: { NearbyConnectionManager.shared.attachments?.closeView?() })
|
||||
@@ -215,9 +234,7 @@ struct DeviceFilePickerButton: View {
|
||||
DeviceButtonLabel(device: device, isSelected: isPreparing || isSelected, progress: isPreparing ? "Preparing".localized() : progressState, progressValue: progressValue)
|
||||
} onResult: { urls, text in
|
||||
isPreparing = false
|
||||
sendModel.urls = urls ?? []
|
||||
sendModel.textToSend = text
|
||||
sendModel.selectDevice(device: device)
|
||||
sendModel.selectDevice(device: device, with: AttachmentDetails(urls: urls ?? [], textToSend: text, shortDescription: ""))
|
||||
} onPrepare: {
|
||||
isPreparing = true
|
||||
}
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
{
|
||||
"sourceLanguage" : "en",
|
||||
"strings" : {
|
||||
"CFBundleDisplayName" : {
|
||||
"comment" : "Bundle display name",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "QuickDrop"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"CFBundleName" : {
|
||||
"comment" : "Bundle name",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : "QuickDropiOS"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"NSHumanReadableCopyright" : {
|
||||
"comment" : "Copyright (human-readable)",
|
||||
"extractionState" : "extracted_with_value",
|
||||
"localizations" : {
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "new",
|
||||
"value" : ""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"NSLocalNetworkUsageDescription" : {
|
||||
"comment" : "Privacy - Local Network Usage Description",
|
||||
"localizations" : {
|
||||
"ar" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "الوصول إلى الشبكة المحلية مطلوب لاكتشاف الأجهزة ونقل الملفات عبر شبكة Wi-Fi الخاصة بك."
|
||||
}
|
||||
},
|
||||
"ca" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cal accés a la xarxa local per detectar dispositius i transferir fitxers a través de la teva xarxa Wi-Fi."
|
||||
}
|
||||
},
|
||||
"cs" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Pro přenos souborů a detekci zařízení přes vaši Wi-Fi síť je třeba povolit přístup k místní síti."
|
||||
}
|
||||
},
|
||||
"da" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Adgang til lokalt netværk er nødvendig for at finde enheder og overføre filer via dit Wi-Fi-netværk."
|
||||
}
|
||||
},
|
||||
"de" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Der Zugriff auf das lokale Netzwerk ist erforderlich, um Geräte zu erkennen und Dateien über WLAN zu übertragen."
|
||||
}
|
||||
},
|
||||
"el" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Απαιτείται πρόσβαση στο τοπικό δίκτυο για ανίχνευση συσκευών και μεταφορά αρχείων μέσω του Wi-Fi δικτύου σας."
|
||||
}
|
||||
},
|
||||
"en" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Local network access is needed to detect devices and transfer files over your Wi-Fi network."
|
||||
}
|
||||
},
|
||||
"en-AU" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Local network access is required to find devices and transfer files over your Wi-Fi network."
|
||||
}
|
||||
},
|
||||
"en-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Local network access is required to find devices and transfer files over your Wi-Fi network."
|
||||
}
|
||||
},
|
||||
"en-GB" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Local network access is required to discover devices and transfer files via your Wi-Fi network."
|
||||
}
|
||||
},
|
||||
"es" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Se necesita acceso a la red local para detectar dispositivos y transferir archivos a través de su red Wi-Fi."
|
||||
}
|
||||
},
|
||||
"es-419" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Se necesita acceso a la red local para detectar dispositivos y transferir archivos por tu red Wi-Fi."
|
||||
}
|
||||
},
|
||||
"fi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Lähiverkkoyhteys tarvitaan laitteiden tunnistamiseen ja tiedostojen siirtoon Wi-Fi-verkossasi."
|
||||
}
|
||||
},
|
||||
"fr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "L’accès au réseau local est nécessaire pour détecter les appareils et transférer des fichiers via votre réseau Wi-Fi."
|
||||
}
|
||||
},
|
||||
"fr-CA" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "L’accès au réseau local est nécessaire pour détecter les appareils et transférer des fichiers sur votre réseau Wi-Fi."
|
||||
}
|
||||
},
|
||||
"he" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "נדרש גישה לרשת המקומית כדי לזהות מכשירים ולהעביר קבצים דרך רשת ה-Wi-Fi שלך."
|
||||
}
|
||||
},
|
||||
"hi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "डिवाइस का पता लगाने और अपने Wi-Fi नेटवर्क पर फाइल ट्रांसफर के लिए लोकल नेटवर्क एक्सेस आवश्यक है।"
|
||||
}
|
||||
},
|
||||
"hr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Pristup lokalnoj mreži potreban je za pronalaženje uređaja i prijenos datoteka putem vaše Wi-Fi mreže."
|
||||
}
|
||||
},
|
||||
"hu" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Helyi hálózati hozzáférés szükséges az eszközök felismeréséhez és a fájlok átviteléhez a Wi-Fi hálózatán keresztül."
|
||||
}
|
||||
},
|
||||
"id" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Akses jaringan lokal diperlukan untuk mendeteksi perangkat dan mentransfer file melalui jaringan Wi-Fi Anda."
|
||||
}
|
||||
},
|
||||
"it" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "È necessario l’accesso alla rete locale per rilevare i dispositivi e trasferire file tramite la tua rete Wi-Fi."
|
||||
}
|
||||
},
|
||||
"ja" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "ローカルネットワークへのアクセスは、デバイスを検出し、Wi-Fi ネットワーク経由でファイルを転送するために必要です。"
|
||||
}
|
||||
},
|
||||
"ko" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "장치를 감지하고 Wi-Fi 네트워크를 통해 파일을 전송하려면 로컬 네트워크 접근이 필요합니다."
|
||||
}
|
||||
},
|
||||
"ms" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Akses rangkaian tempatan diperlukan untuk mengesan peranti dan memindahkan fail melalui rangkaian Wi-Fi anda."
|
||||
}
|
||||
},
|
||||
"nb" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Tilgang til lokalt nettverk er nødvendig for å oppdage enheter og overføre filer via Wi-Fi-nettverket ditt."
|
||||
}
|
||||
},
|
||||
"nl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Lokale netwerktoegang is nodig om apparaten te detecteren en bestanden over uw Wi-Fi-netwerk te verzenden."
|
||||
}
|
||||
},
|
||||
"pl" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Dostęp do sieci lokalnej jest potrzebny, aby wykrywać urządzenia i przesyłać pliki przez Twoją sieć Wi-Fi."
|
||||
}
|
||||
},
|
||||
"pt-BR" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "O acesso à rede local é necessário para detectar dispositivos e transferir arquivos pela sua rede Wi-Fi."
|
||||
}
|
||||
},
|
||||
"pt-PT" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "O acesso à rede local é necessário para detetar dispositivos e transferir ficheiros através da sua rede Wi-Fi."
|
||||
}
|
||||
},
|
||||
"ro" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Accesul la rețeaua locală este necesar pentru a detecta dispozitivele și a transfera fișiere prin rețeaua Wi-Fi."
|
||||
}
|
||||
},
|
||||
"ru" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Доступ к локальной сети необходим для обнаружения устройств и передачи файлов через вашу сеть Wi-Fi."
|
||||
}
|
||||
},
|
||||
"sv" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Åtkomst till lokalt nätverk krävs för att upptäcka enheter och överföra filer via ditt Wi-Fi-nätverk."
|
||||
}
|
||||
},
|
||||
"th" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "การเข้าถึงเครือข่ายภายในเครื่องจำเป็นสำหรับการตรวจหาดีไวซ์และการถ่ายโอนไฟล์ผ่านเครือข่าย Wi-Fi ของคุณ"
|
||||
}
|
||||
},
|
||||
"tr" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cihazları algılamak ve dosya aktarmak için yerel ağa erişim gereklidir."
|
||||
}
|
||||
},
|
||||
"uk" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Доступ до локальної мережі потрібен для виявлення пристроїв та передавання файлів через вашу мережу Wi-Fi."
|
||||
}
|
||||
},
|
||||
"vi" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "Cần truy cập mạng nội bộ để phát hiện thiết bị và truyền tệp qua Wi-Fi của bạn."
|
||||
}
|
||||
},
|
||||
"zh-Hans" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "需要本地网络访问以检测设备并通过您的 Wi-Fi 网络传输文件。"
|
||||
}
|
||||
},
|
||||
"zh-Hant" : {
|
||||
"stringUnit" : {
|
||||
"state" : "translated",
|
||||
"value" : "需要本機網路存取權才能偵測裝置並透過 Wi-Fi 網路傳輸檔案。"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"version" : "1.0"
|
||||
}
|
||||
@@ -174,7 +174,7 @@ class ReceiveModel: ObservableObject, InboundAppDelegate {
|
||||
showCopiedToClipboardAlert()
|
||||
}
|
||||
|
||||
let currentCount = incomingTransmissionCount()
|
||||
let currentCount = Settings.shared.incomingTransmissionCount
|
||||
|
||||
#if os(macOS)
|
||||
if currentCount == 0 {
|
||||
@@ -184,7 +184,7 @@ class ReceiveModel: ObservableObject, InboundAppDelegate {
|
||||
}
|
||||
#endif
|
||||
|
||||
UserDefaults.standard.set(currentCount + 1, forKey: UserDefaultsKeys.transmissionCount.rawValue)
|
||||
Settings.shared.incomingTransmissionCount = currentCount + 1
|
||||
log("[ReceiveModel] Successful transmission. Current count: \(currentCount)")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import LUI
|
||||
|
||||
class SendModel: ObservableObject, OutboundAppDelegate {
|
||||
|
||||
@Published var showQrCodeView: Bool = false
|
||||
|
||||
@Published var foundDevices: [RemoteDeviceInfo] = []
|
||||
@Published var selectedDevice: RemoteDeviceInfo?
|
||||
|
||||
@@ -24,29 +26,34 @@ class SendModel: ObservableObject, OutboundAppDelegate {
|
||||
private var connectionEstablished = false
|
||||
private var timeoutDispatchWorkItem: DispatchWorkItem? = nil
|
||||
|
||||
|
||||
init() {
|
||||
NearbyConnectionManager.shared.startDeviceDiscovery()
|
||||
NearbyConnectionManager.shared.addShareExtensionDelegate(self)
|
||||
}
|
||||
|
||||
|
||||
func addDevice(device: RemoteDeviceInfo) {
|
||||
withAnimation(.smooth) {
|
||||
foundDevices.append(device)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func removeDevice(id: String) {
|
||||
withAnimation(.smooth) {
|
||||
foundDevices.removeAll { $0.id == id }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func connectionWasEstablished(pinCode: String) {
|
||||
connectionEstablished = true
|
||||
progressState = String(format: "PinCode".localized(), arguments: [pinCode])
|
||||
progressValue = 0
|
||||
}
|
||||
|
||||
|
||||
func connectionFailed(error: any Error) {
|
||||
|
||||
#if os(iOS)
|
||||
@@ -59,14 +66,17 @@ class SendModel: ObservableObject, OutboundAppDelegate {
|
||||
selectedDevice = nil
|
||||
}
|
||||
|
||||
|
||||
func transferAccepted() {
|
||||
progressState = "Sending".localized()
|
||||
}
|
||||
|
||||
|
||||
func transferProgress(progress: Double) {
|
||||
progressValue = progress
|
||||
}
|
||||
|
||||
|
||||
func transferFinished() {
|
||||
|
||||
#if os(iOS)
|
||||
@@ -78,13 +88,28 @@ class SendModel: ObservableObject, OutboundAppDelegate {
|
||||
progressState = "TransferFinished".localized()
|
||||
|
||||
NearbyConnectionManager.shared.attachments?.closeView?()
|
||||
|
||||
#if !EXTENSION
|
||||
requestReviewOnce()
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
func startTransferWithQrCode(device: RemoteDeviceInfo) {
|
||||
selectDevice(device: device)
|
||||
showQrCodeView = false
|
||||
|
||||
#if EXTENSION
|
||||
if let attachments = NearbyConnectionManager.shared.attachments {
|
||||
self.selectDevice(device:device, with: attachments)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
func selectDevice(device: RemoteDeviceInfo) {
|
||||
|
||||
func selectDevice(device: RemoteDeviceInfo, with attachments: AttachmentDetails) {
|
||||
|
||||
self.urls = attachments.urls
|
||||
self.textToSend = attachments.textToSend
|
||||
|
||||
// already selected, cancel transfer
|
||||
if device == selectedDevice {
|
||||
@@ -94,6 +119,7 @@ class SendModel: ObservableObject, OutboundAppDelegate {
|
||||
NearbyConnectionManager.shared.cancelOutgoingTransfer(id: device.id!)
|
||||
}
|
||||
else {
|
||||
|
||||
progressValue = 0
|
||||
progressState = "Connecting".localized()
|
||||
selectedDevice = device
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "الوصول إلى الشبكة المحلية مطلوب لاكتشاف الأجهزة ونقل الملفات عبر شبكة Wi-Fi الخاصة بك.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "Der Zugriff auf das lokale Netzwerk ist erforderlich, um Geräte zu erkennen und Dateien über WLAN zu übertragen.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "Se necesita acceso a la red local para detectar dispositivos y transferir archivos a través de su red Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "L’accès au réseau local est nécessaire pour détecter les appareils et transférer des fichiers via votre réseau Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "Helyi hálózati hozzáférés szükséges az eszközök felismeréséhez és a fájlok átviteléhez a Wi-Fi hálózatán keresztül.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "È necessario l’accesso alla rete locale per rilevare i dispositivi e trasferire file tramite la tua rete Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "ローカルネットワークへのアクセスは、デバイスを検出し、Wi-Fi ネットワーク経由でファイルを転送するために必要です。";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "장치를 감지하고 Wi-Fi 네트워크를 통해 파일을 전송하려면 로컬 네트워크 접근이 필요합니다.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "Lokale netwerktoegang is nodig om apparaten te detecteren en bestanden over uw Wi-Fi-netwerk te verzenden.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "O acesso à rede local é necessário para detectar dispositivos e transferir arquivos pela sua rede Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "O acesso à rede local é necessário para detetar dispositivos e transferir ficheiros através da sua rede Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "Accesul la rețeaua locală este necesar pentru a detecta dispozitivele și a transfera fișiere prin rețeaua Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "Доступ к локальной сети необходим для обнаружения устройств и передачи файлов через вашу сеть Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "การเข้าถึงเครือข่ายภายในเครื่องจำเป็นสำหรับการตรวจหาดีไวซ์และการถ่ายโอนไฟล์ผ่านเครือข่าย Wi-Fi ของคุณ";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "Доступ до локальної мережі потрібен для виявлення пристроїв та передавання файлів через вашу мережу Wi-Fi.";
|
||||
@@ -1,10 +0,0 @@
|
||||
/*
|
||||
InfoPlist.strings
|
||||
AirGuard
|
||||
|
||||
Created by Leon Böttger on 23.08.22.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
NSLocalNetworkUsageDescription = "需要本地网络访问以检测设备并通过您的 Wi-Fi 网络传输文件。";
|
||||
@@ -896,9 +896,9 @@ Neither the name of Google Inc. nor the names of its contributors may be used to
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
RNDeviceName
|
||||
https://github.com/souzainf3/RNDeviceName
|
||||
Copyright (c) 2014 Romilson Nunes <souzainf3@yahoo.com.br>
|
||||
DeviceKit
|
||||
https://github.com/devicekit/DeviceKit
|
||||
Copyright (c) 2015 Dennis Weissmann
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -14,5 +14,7 @@
|
||||
<key>NSExtensionPrincipalClass</key>
|
||||
<string>$(PRODUCT_MODULE_NAME).ShareViewController</string>
|
||||
</dict>
|
||||
<key>UIDesignRequiresCompatibility</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||