diff options
| -rw-r--r-- | Hotline/Hotline/HotlineDataBuilder.swift | 33 | ||||
| -rw-r--r-- | Hotline/Hotline/HotlineExtensions.swift | 201 | ||||
| -rw-r--r-- | Hotline/Hotline/HotlineTransferClient.swift | 178 | ||||
| -rw-r--r-- | Hotline/Models/FilePreview.swift | 3 | ||||
| -rw-r--r-- | Hotline/Models/Hotline.swift | 67 |
5 files changed, 295 insertions, 187 deletions
diff --git a/Hotline/Hotline/HotlineDataBuilder.swift b/Hotline/Hotline/HotlineDataBuilder.swift index 87ae966..440518a 100644 --- a/Hotline/Hotline/HotlineDataBuilder.swift +++ b/Hotline/Hotline/HotlineDataBuilder.swift @@ -3,11 +3,16 @@ import Foundation enum DataEndianness { case big case little + + static let system: DataEndianness = { + let number: UInt32 = 0x12345678 + return number == number.littleEndian ? .little : .big + }() } @resultBuilder struct DataBuilder { - static var defaultEndian: DataEndianness = .little + static var defaultEndian: DataEndianness = .system static func buildBlock(_ components: Data...) -> Data { components.reduce(Data(), +) @@ -42,24 +47,18 @@ struct DataBuilder { msecs = components.milliseconds } - year = DataBuilder.defaultEndian == .big ? year.bigEndian : year.littleEndian - secs = DataBuilder.defaultEndian == .big ? secs.bigEndian : secs.littleEndian - msecs = DataBuilder.defaultEndian == .big ? msecs.bigEndian : msecs.littleEndian + year = DataBuilder.defaultEndian == .little ? year.littleEndian : year.bigEndian + secs = DataBuilder.defaultEndian == .little ? secs.littleEndian : secs.bigEndian + msecs = DataBuilder.defaultEndian == .little ? msecs.littleEndian : msecs.bigEndian - withUnsafeBytes(of: year) { dateData.append(Data($0)) } - withUnsafeBytes(of: msecs) { dateData.append(Data($0)) } - withUnsafeBytes(of: secs) { dateData.append(Data($0)) } + dateData.append(withUnsafeBytes(of: year) { Data($0) }) + dateData.append(withUnsafeBytes(of: msecs) { Data($0) }) + dateData.append(withUnsafeBytes(of: secs) { Data($0) }) return dateData } - static func buildExpression(_ expression: Int) -> Data { - print("ADDING BYTE:", expression) - return withUnsafeBytes(of: UInt8(expression)) { Data($0) } - } - static func buildExpression<T: FixedWidthInteger>(_ expression: (T, DataEndianness)) -> Data { - print("ADDING INTEGER:", expression) let value = expression.1 == .little ? expression.0.littleEndian : expression.0.bigEndian return withUnsafeBytes(of: value) { Data($0) } } @@ -81,10 +80,16 @@ struct DataBuilder { static func buildOptional(_ component: Data?) -> Data { component ?? Data() } + + static func buildFinalResult(_ component: Data) -> Data { + var data = Data() + data.append(component) + return data + } } extension Data { - init(endian: DataEndianness = .little, @DataBuilder _ content: () -> Data) { + init(endian: DataEndianness = .system, @DataBuilder _ content: () -> Data) { DataBuilder.defaultEndian = endian self = content() } diff --git a/Hotline/Hotline/HotlineExtensions.swift b/Hotline/Hotline/HotlineExtensions.swift index ac16a39..fd57971 100644 --- a/Hotline/Hotline/HotlineExtensions.swift +++ b/Hotline/Hotline/HotlineExtensions.swift @@ -1,4 +1,5 @@ import Foundation +import CoreServices enum LineEnding { case lf // Unix-style (\n) @@ -49,38 +50,201 @@ extension String { } extension FileManager { - func updateFileProgress(_ fileURL: URL, progress: Double) { - let filePath = fileURL.path(percentEncoded: false) - let fileAttributes = try? self.attributesOfItem(atPath: filePath) + static var extensionToHFSCreator: [String: UInt32] = [ + // Documents + "txt": "ttxt".fourCharCode(), + "rtf": "MSWD".fourCharCode(), + "doc": "MSWD".fourCharCode(), + "qxd": "XPR3".fourCharCode(), + "indd": "InDn".fourCharCode(), + "idd": "InDn".fourCharCode(), -// let extendedAttributes = fileAttributes[] + // Spreadsheets + "csv": "ttxt".fourCharCode(), + "xls": "XCEL".fourCharCode(), + "xlsx": "XCEL".fourCharCode(), + "numbers": "NMBR".fourCharCode(), - print("ATTRIBUTES: ", fileAttributes) + // Presentations + "ppt": "PPT3".fourCharCode(), + "key": "KEYN".fourCharCode(), -// let blah = Progress(totalUnitCount: 100) -// -// blah.fileTotalCount = 1 -// blah.fileOperationKind = .downloading -// blah.fileCompletedCount = 0 - } + // Images + "ai": "ART5".fourCharCode(), + "jpg": "8BIM".fourCharCode(), + "jpeg": "8BIM".fourCharCode(), + "png": "8BIM".fourCharCode(), + "gif": "8BIM".fourCharCode(), + "tiff": "8BIM".fourCharCode(), + "ico": "8BIM".fourCharCode(), + "bmp": "8BIM".fourCharCode(), + "eps": "8BIM".fourCharCode(), + "ps": "8BIM".fourCharCode(), + "psd": "8BIM".fourCharCode(), + "pict": "8BIM".fourCharCode(), + "tga": "8BIM".fourCharCode(), + + // Archives + "zip": "SITx".fourCharCode(), + "sit": "SITx".fourCharCode(), + "dmg": "ddsk".fourCharCode(), + "sea": "SITx".fourCharCode(), + + // Programming + "swift": "R*ch".fourCharCode(), + "java": "R*ch".fourCharCode(), + "py": "R*ch".fourCharCode(), + "c": "R*ch".fourCharCode(), + "cpp": "R*ch".fourCharCode(), + "cp": "R*ch".fourCharCode(), + "h": "R*ch".fourCharCode(), + "js": "R*ch".fourCharCode(), + "html": "sfri".fourCharCode(), + "css": "sfri".fourCharCode(), + "php": "R*ch".fourCharCode(), + "json": "R*ch".fourCharCode(), + "md": "R*ch".fourCharCode(), + "log": "R*ch".fourCharCode(), + "xml": "R*ch".fourCharCode(), + ] + + static var extensionToHFSType: [String: UInt32] = [ + // Documents + "txt": "TEXT".fourCharCode(), + "rtf": "RTF ".fourCharCode(), + "doc": "WDBN".fourCharCode(), + "docx": "W8BN".fourCharCode(), + "prd": "WPRD".fourCharCode(), + "wpd": "WP5".fourCharCode(), + "pdf": "PDF ".fourCharCode(), + "qxd": "XDOC".fourCharCode(), + "indd": "inDd".fourCharCode(), + "idd": "inDd".fourCharCode(), + + // Spreadsheets + "csv": "TEXT".fourCharCode(), + "xls": "XLS ".fourCharCode(), + "xlsx": "XLSX".fourCharCode(), + "numbers": "NMBR".fourCharCode(), + + // Presentations + "ppt": "PPT3".fourCharCode(), + "key": "KEYN".fourCharCode(), + + // Images + "jpg": "JPEG".fourCharCode(), + "jpeg": "JPEG".fourCharCode(), + "png": "PNGf".fourCharCode(), + "gif": "GIFf".fourCharCode(), + "tiff": "TIFF".fourCharCode(), + "ico": "ICO ".fourCharCode(), + "bmp": "BMPf".fourCharCode(), + "eps": "EPSF".fourCharCode(), + "ps": "EPSF".fourCharCode(), + "psd": "8BPS".fourCharCode(), + "pict": "PICT".fourCharCode(), + "tga": "TPIC".fourCharCode(), + "swf": "SWFL".fourCharCode(), + + // Audio + "mp3": "Mp3 ".fourCharCode(), + "m4a": "M4A ".fourCharCode(), + "aac": "caff".fourCharCode(), + "wav": "WAVE".fourCharCode(), + "aiff": "AIFF".fourCharCode(), + "midi": "Midi".fourCharCode(), + "snd": "snd ".fourCharCode(), + + // Video + "mp4": "M4V ".fourCharCode(), + "mpeg": "MPG ".fourCharCode(), + "mpg2": "MPG2".fourCharCode(), + "mov": "MooV".fourCharCode(), + "avi": "VfW ".fourCharCode(), + "wmv": "WMV ".fourCharCode(), + + // Archives + "zip": "ZIP ".fourCharCode(), + "rar": "RAR ".fourCharCode(), + "7z": "7ZIP".fourCharCode(), + "tar": "TAR ".fourCharCode(), + "gz": "GZIP".fourCharCode(), + "sit": "SITx".fourCharCode(), + "dmg": "udif".fourCharCode(), + "sea": "SITx".fourCharCode(), + "cdr": "CDRW".fourCharCode(), + + // Programming + "swift": "TEXT".fourCharCode(), + "java": "TEXT".fourCharCode(), + "py": "TEXT".fourCharCode(), + "c": "TEXT".fourCharCode(), + "cpp": "TEXT".fourCharCode(), + "cp": "TEXT".fourCharCode(), + "h": "TEXT".fourCharCode(), + "js": "TEXT".fourCharCode(), + "html": "TEXT".fourCharCode(), + "css": "TEXT".fourCharCode(), + "php": "TEXT".fourCharCode(), + "json": "TEXT".fourCharCode(), + "md": "TEXT".fourCharCode(), + "log": "TEXT".fourCharCode(), + "xml": "TEXT".fourCharCode(), + + // Fonts + "ttf": "tfil".fourCharCode(), + ] func getHFSTypeAndCreator(_ fileURL: URL) throws -> (hfsCreator: UInt32, hfsType: UInt32) { let filePath = fileURL.path(percentEncoded: false) let fileAttributes: [FileAttributeKey: Any] = try self.attributesOfItem(atPath: filePath) + let fileExtension = fileURL.pathExtension.lowercased() - var creator: UInt32 = 0 - if let creatorCode: NSNumber = fileAttributes[.hfsCreatorCode] as? NSNumber { + var creator: UInt32 = "????".fourCharCode() + if let creatorCode: NSNumber = fileAttributes[.hfsCreatorCode] as? NSNumber, + creatorCode.uint32Value != 0 { creator = creatorCode.uint32Value } + if creator == "????".fourCharCode() { + if let possibleCreator = FileManager.extensionToHFSCreator[fileExtension] { + creator = possibleCreator + } + } - var type: UInt32 = 0 - if let typeCode: NSNumber = fileAttributes[.hfsTypeCode] as? NSNumber { + var type: UInt32 = "????".fourCharCode() + if let typeCode: NSNumber = fileAttributes[.hfsTypeCode] as? NSNumber, + typeCode.uint32Value != 0 { type = typeCode.uint32Value } + if type == "????".fourCharCode() { + if let possibleType = FileManager.extensionToHFSType[fileExtension] { + type = possibleType + } + } return (hfsCreator: creator, hfsType: type) } + func getFinderComment(_ fileURL: URL) throws -> String { + let filePath = fileURL.path(percentEncoded: false) + let fileAttributes: [FileAttributeKey: Any] = try self.attributesOfItem(atPath: filePath) + + if let extendedAttributesData = fileAttributes[FileAttributeKey(rawValue: "NSFileExtendedAttributes")], + let extendedAttributes = extendedAttributesData as? [FileAttributeKey: Any] { + print(extendedAttributes) + + if let commentPlistDataAttribute = extendedAttributes[FileAttributeKey(rawValue: "com.apple.metadata:kMDItemFinderComment")], + let commentPlistData = commentPlistDataAttribute as? Data { + if let plist = try? PropertyListSerialization.propertyList(from: commentPlistData, options: [], format: nil), + let plistString = plist as? String { + return plistString + } + } + } + + return "" + } + func getCreatedAndModifiedDates(_ fileURL: URL) -> (createdDate: Date, modifiedDate: Date) { let filePath = fileURL.path(percentEncoded: false) @@ -90,6 +254,8 @@ extension FileManager { return (createdDate: Date(), modifiedDate: Date()) } + print("GOT CREATED DATE: ", createdNSDate) + return (createdDate: createdNSDate as Date, modifiedDate: modifiedNSDate as Date) } @@ -115,7 +281,6 @@ extension FileManager { let length = getxattr(fileSystemPath, name, nil, 0, 0, 0) guard length >= 0 else { throw NSError(domain: NSPOSIXErrorDomain, code: Int(errno), userInfo: [NSLocalizedDescriptionKey: String(cString: strerror(errno))]) } - var data = Data(count: length) if length == 0 { return data @@ -593,6 +758,10 @@ extension Array where Element == UInt8 { } extension Data { + func hexDump() -> String { + return self.map { String(format: "%02x", $0) }.joined(separator: " ") + } + init(_ val: UInt8) { self.init() self.appendUInt8(val) diff --git a/Hotline/Hotline/HotlineTransferClient.swift b/Hotline/Hotline/HotlineTransferClient.swift index 262c5ed..4322c70 100644 --- a/Hotline/Hotline/HotlineTransferClient.swift +++ b/Hotline/Hotline/HotlineTransferClient.swift @@ -21,10 +21,19 @@ enum HotlineTransferStatus: Equatable { case connecting case connected case progress(Double) + case completing case completed case failed(HotlineFileClientError) } +enum HotlineFileForkType: UInt32 { + case none = 0 + case unsupported = 1 + case info = 0x494E464F // 'INFO' + case data = 0x44415441 // 'DATA' + case resource = 1296122706 // 'MACR' +} + protocol HotlineTransferDelegate: AnyObject { func hotlineTransferStatusChanged(client: HotlineTransferClient, reference: UInt32, status: HotlineTransferStatus, timeRemaining: TimeInterval) } @@ -183,6 +192,17 @@ class HotlineFileUploadClient: HotlineTransferClient { print("HotlineFileClient: Failed to finish transfer.") self?.invalidate() self?.status = .failed(.failedToUpload) + case .completing: + print("HotlineFileClient: Completed.") + self?.invalidate() + self?.status = .completed + DispatchQueue.main.async { [weak self] in + if let s = self { + s.delegate?.hotlineFileUploadComplete(client: s, reference: s.referenceNumber) + } + } + case .completed: + self?.invalidate() default: break } @@ -214,9 +234,23 @@ class HotlineFileUploadClient: HotlineTransferClient { self.fileResourceURL?.stopAccessingSecurityScopedResource() } + private func sendComplete() { + guard let c = self.connection else { + self.invalidate() + print("HotlineFileUploadClient: invalid connection to send data.") + return + } + + self.status = .completing + + c.send(content: nil, contentContext: .finalMessage, completion: .contentProcessed({ error in + })) + } + private func sendFileData(_ data: Data) { guard let c = self.connection else { self.invalidate() + print("HotlineFileUploadClient: invalid connection to send data.") return } @@ -257,6 +291,7 @@ class HotlineFileUploadClient: HotlineTransferClient { self.payloadSize UInt32.zero } +// var magicData = Data() // magicData.appendUInt32("HTXF".fourCharCode()) // magicData.appendUInt32(self.referenceNumber) // magicData.appendUInt32(self.payloadSize) @@ -273,7 +308,7 @@ class HotlineFileUploadClient: HotlineTransferClient { case .fileInfoForkHeader: print("Upload: Sending info fork header") - let header = HotlineFileForkHeader(type: "INFO".fourCharCode(), dataSize: UInt32(self.infoForkData.count)) + let header = HotlineFileForkHeader(type: HotlineFileForkType.info.rawValue, dataSize: UInt32(self.infoForkData.count)) self.stage = .fileInfoFork self.sendFileData(header.data()) @@ -294,7 +329,7 @@ class HotlineFileUploadClient: HotlineTransferClient { self.fileHandle = fh self.stage = .fileDataFork - let header = HotlineFileForkHeader(type: "DATA".fourCharCode(), dataSize: self.dataForkSize) + let header = HotlineFileForkHeader(type: HotlineFileForkType.data.rawValue, dataSize: self.dataForkSize) print("Upload: Sending data fork header \(self.dataForkSize)") self.sendFileData(header.data()) @@ -325,7 +360,7 @@ class HotlineFileUploadClient: HotlineTransferClient { fallthrough } - print("Upload: Sending Data Fork \(String(describing: fileData?.count))") + print("Upload: Sending data Fork \(String(describing: fileData?.count))") self.sendFileData(fileData!) } catch { @@ -349,7 +384,7 @@ class HotlineFileUploadClient: HotlineTransferClient { return } - let header = HotlineFileForkHeader(type: "MACR".fourCharCode(), dataSize: self.resourceForkSize) + let header = HotlineFileForkHeader(type: HotlineFileForkType.resource.rawValue, dataSize: self.resourceForkSize) self.fileHandle = fh self.stage = .fileResourceFork @@ -387,12 +422,7 @@ class HotlineFileUploadClient: HotlineTransferClient { case .fileComplete: print("Upload: Complete!") - self.status = .completed - self.invalidate() - - DispatchQueue.main.sync { - self.delegate?.hotlineFileUploadComplete(client: self, reference: self.referenceNumber) - } + self.sendComplete() } } } @@ -719,15 +749,6 @@ class HotlineFileDownloadClient: HotlineTransferClient { return } - - // Original method -// var headerData = Data() -// headerData.appendUInt32("HTXF".fourCharCode()) -// headerData.appendUInt32(self.referenceNumber) -// headerData.appendUInt32(0) -// headerData.appendUInt32(0) - - // Result builder method let headerData = Data(endian: .big) { "HTXF".fourCharCode() self.referenceNumber @@ -871,34 +892,26 @@ class HotlineFileDownloadClient: HotlineTransferClient { } case .fileResourceFork: if self.fileBytes.count > 0 { -// if let f = self.fileResourceHandle { -// do { - var dataToWrite = self.fileBytes - - if dataToWrite.count >= self.fileCurrentForkBytesLeft { - dataToWrite = self.fileBytes.subdata(in: 0..<self.fileCurrentForkBytesLeft) - self.fileBytes.removeSubrange(0..<self.fileCurrentForkBytesLeft) - - self.transferStage = .fileForkHeader - self.fileCurrentForkBytesLeft = 0 - self.fileCurrentForkHeader = nil - - keepProcessing = true - } - else { - self.fileCurrentForkBytesLeft -= dataToWrite.count - self.fileBytes = Data() - } - - print("WRITING TO RESOURCE FORK", dataToWrite.count) - - self.fileResourceBytes.append(dataToWrite) -// try f.write(contentsOf: dataToWrite) -// } -// catch { -// print("DOWNLOAD WRITE ERROR", error) -// } -// } + var dataToWrite = self.fileBytes + + if dataToWrite.count >= self.fileCurrentForkBytesLeft { + dataToWrite = self.fileBytes.subdata(in: 0..<self.fileCurrentForkBytesLeft) + self.fileBytes.removeSubrange(0..<self.fileCurrentForkBytesLeft) + + self.transferStage = .fileForkHeader + self.fileCurrentForkBytesLeft = 0 + self.fileCurrentForkHeader = nil + + keepProcessing = true + } + else { + self.fileCurrentForkBytesLeft -= dataToWrite.count + self.fileBytes = Data() + } + + print("WRITING TO RESOURCE FORK", dataToWrite.count) + + self.fileResourceBytes.append(dataToWrite) } case .fileUnsupportedFork: if self.fileBytes.count > 0 { @@ -988,7 +1001,7 @@ class HotlineFileDownloadClient: HotlineTransferClient { filePath = folderURL.generateUniqueFilePath(filename: name) } - var fileAttributes: [FileAttributeKey : Any] = [:] + var fileAttributes: [FileAttributeKey: Any] = [:] if let creatorCode = self.fileInfoFork?.creator { fileAttributes[.hfsCreatorCode] = creatorCode as NSNumber } @@ -1001,6 +1014,13 @@ class HotlineFileDownloadClient: HotlineTransferClient { if let modifiedDate = self.fileInfoFork?.modifiedDate { fileAttributes[.modificationDate] = modifiedDate as NSDate } + if let comment = self.fileInfoFork?.comment { + if let commentPlistData = try? PropertyListSerialization.data(fromPropertyList: comment, format: .binary, options: 0) { + fileAttributes[FileAttributeKey(rawValue: "NSFileExtendedAttributes")] = [ + FileAttributeKey(rawValue: "com.apple.metadata:kMDItemFinderComment"): commentPlistData + ] + } + } if FileManager.default.createFile(atPath: filePath, contents: nil, attributes: fileAttributes) { if let h = FileHandle(forWritingAtPath: filePath) { @@ -1034,7 +1054,6 @@ struct HotlineFileHeader { self.format = data.readUInt32(at: 0)! self.version = data.readUInt16(at: 4)! // 16 bytes of reserved data sits here. Skip it. - // self.reserved = data.readData(at: 4 + 2, length: 16) self.forkCount = data.readUInt16(at: 4 + 2 + 16)! } @@ -1048,10 +1067,10 @@ struct HotlineFileHeader { let resourceURL = fileURL.appendingPathComponent("..namedfork/rsrc") if FileManager.default.fileExists(atPath: resourceURL.path(percentEncoded: false)) { - self.forkCount = 2 + self.forkCount = 3 } else { - self.forkCount = 1 + self.forkCount = 2 } } @@ -1062,15 +1081,6 @@ struct HotlineFileHeader { Data(repeating: 0, count: 16) self.forkCount } - -// var d = Data() -// -// d.appendUInt32(self.format) -// d.appendUInt16(self.version) -// d.appendZeros(count: 16) -// d.appendUInt16(self.forkCount) -// -// return d } } @@ -1108,27 +1118,18 @@ struct HotlineFileForkHeader { UInt32.zero self.dataSize } - -// var d = Data() -// -// d.appendUInt32(self.forkType) -// d.appendUInt32(self.compressionType) -// d.appendUInt32(0) -// d.appendUInt32(self.dataSize) -// -// return d } var isInfoFork: Bool { - return self.forkType == "INFO".fourCharCode() + return self.forkType == HotlineFileForkType.info.rawValue } var isDataFork: Bool { - return self.forkType == "DATA".fourCharCode() + return self.forkType == HotlineFileForkType.data.rawValue } var isResourceFork: Bool { - return self.forkType == "MACR".fourCharCode() + return self.forkType == HotlineFileForkType.resource.rawValue } } @@ -1175,7 +1176,8 @@ struct HotlineFileInfoFork { self.nameScript = 0 self.name = fileURL.lastPathComponent - self.comment = nil + let fileComment = try? FileManager.default.getFinderComment(fileURL) + self.comment = fileComment ?? "" self.headerSize = 0 } @@ -1248,7 +1250,9 @@ struct HotlineFileInfoFork { } func data() -> Data { - Data(endian: .big) { + let fileName = self.name.data(using: .macOSRoman)! + + let data = Data(endian: .big) { self.platform self.type self.creator @@ -1258,26 +1262,14 @@ struct HotlineFileInfoFork { self.createdDate self.modifiedDate self.nameScript - UInt16(self.name.count) - (self.name, .macOSRoman) + UInt16(fileName.count) + fileName + if let commentData = self.comment?.data(using: .macOSRoman) { + UInt16(commentData.count) + commentData + } } - -// var d = Data() -// -// d.appendUInt32(self.platform) -// d.appendUInt32(self.type) -// d.appendUInt32(self.creator) -// d.appendUInt32(self.flags) -// d.appendUInt32(self.platformFlags) -// d.appendZeros(count: 32) -// d.appendDate(self.createdDate) -// d.appendDate(self.modifiedDate) -// d.appendUInt16(self.nameScript) -// -// d.appendUInt16(UInt16(self.name.count)) -// d.appendString(self.name, encoding: .macOSRoman) -// -// return d + return data } } diff --git a/Hotline/Models/FilePreview.swift b/Hotline/Models/FilePreview.swift index 3960a0d..e5f49a3 100644 --- a/Hotline/Models/FilePreview.swift +++ b/Hotline/Models/FilePreview.swift @@ -80,6 +80,9 @@ final class FilePreview: HotlineFilePreviewClientDelegate { case .failed(_): state = .failed progress = 0.0 + case .completing: + state = .loading + progress = 1.0 case .completed: state = .loaded progress = 1.0 diff --git a/Hotline/Models/Hotline.swift b/Hotline/Models/Hotline.swift index 69a11d3..e69116e 100644 --- a/Hotline/Models/Hotline.swift +++ b/Hotline/Models/Hotline.swift @@ -934,12 +934,13 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega b.delegate = nil self.bannerClient = nil } + case .completing: + break case .completed: if let transfer = self.transfers.first(where: { $0.id == reference }) { transfer.completed = true transfer.timeRemaining = 0.0 } - break } } @@ -949,48 +950,6 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega } } -// func hotlineFileReceivedInfo(client: HotlineFileClient, reference: UInt32, info: HotlineFileInfoFork) { -// if let transfer = self.transfers.first(where: { $0.id == reference }) { -// transfer.title = info.name -// } -// } - -// func hotlineTransferStatusChanged(client: HotlineTransferClient, status: HotlineTransferStatus, timeRemaining: TimeInterval) { -// switch status { -// case .unconnected: -// break -// case .connecting: -// break -// case .connected: -// break -// case .progress(let progress): -// if let transfer = self.transfers.first(where: { $0.id == client.referenceNumber }) { -// transfer.progress = progress -// transfer.timeRemaining = timeRemaining -// transfer.progressCallback?(transfer, progress) -// } -// case .failed(_): -// if let i = self.downloads.firstIndex(where: { $0.referenceNumber == client.referenceNumber }) { -// self.downloads.remove(at: i) -// } -// if let transfer = self.transfers.first(where: { $0.id == client.referenceNumber }) { -// transfer.failed = true -// transfer.timeRemaining = 0.0 -// } -// if let b = self.bannerClient, reference == b.referenceNumber { -// b.delegate = nil -// self.bannerClient = nil -// } -// case .completed: -// if let transfer = self.transfers.first(where: { $0.id == client.referenceNumber }) { -// transfer.completed = true -// transfer.timeRemaining = 0.0 -// } -// break -// } -// } - - func hotlineFilePreviewComplete(client: HotlineFilePreviewClient, reference: UInt32, data: Data) { if let b = self.bannerClient, b.referenceNumber == reference { #if os(macOS) @@ -1010,27 +969,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega self.downloads.remove(at: i) } } - -// func hotlineFileDownloadedData(client: HotlineFileClient, reference: UInt32, data: Data) { -// if let b = self.bannerClient, b.referenceNumber == reference { -// #if os(macOS) -// self.bannerImage = NSImage(data: data) -// #elseif os(iOS) -// self.bannerImage = UIImage(data: data) -// #endif -// } -// else -// if let i = self.transfers.firstIndex(where: { $0.id == reference }) { -// let transfer = self.transfers[i] -// transfer.previewCallback?(transfer, data) -// self.transfers.remove(at: i) -// } -// -// if let i = self.downloads.firstIndex(where: { $0.referenceNumber == reference }) { -// self.downloads.remove(at: i) -// } -// } - + func hotlineFileDownloadComplete(client: HotlineFileDownloadClient, reference: UInt32, at: URL) { if let i = self.transfers.firstIndex(where: { $0.id == reference }) { let transfer = self.transfers[i] |