aboutsummaryrefslogtreecommitdiff
path: root/Hotline/State
diff options
context:
space:
mode:
Diffstat (limited to 'Hotline/State')
-rw-r--r--Hotline/State/AppUpdate.swift9
-rw-r--r--Hotline/State/FilePreviewState.swift153
-rw-r--r--Hotline/State/HotlineState.swift22
-rw-r--r--Hotline/State/ServerState.swift2
4 files changed, 84 insertions, 102 deletions
diff --git a/Hotline/State/AppUpdate.swift b/Hotline/State/AppUpdate.swift
index 601859e..558a296 100644
--- a/Hotline/State/AppUpdate.swift
+++ b/Hotline/State/AppUpdate.swift
@@ -35,8 +35,6 @@ final class AppUpdate {
case manual
}
- // MARK: - Public State
-
var isChecking = false
var isDownloading = false
var showWindow = false
@@ -55,7 +53,7 @@ final class AppUpdate {
private let remindDateKey = "update.remind.date"
private let lastPromptedVersionKey = "update.last.prompt.version"
- // MARK: - Public API
+ // MARK: - API
func checkForUpdatesOnLaunch() async {
await checkForUpdates(trigger: .automatic)
@@ -100,7 +98,7 @@ final class AppUpdate {
resetAndCloseWindow()
}
- // MARK: - Internal Logic
+ // MARK: - Implementation
private func checkForUpdates(trigger: CheckTrigger) async {
await MainActor.run {
@@ -259,8 +257,7 @@ final class AppUpdate {
private func downloadRelease(_ release: UpdateReleaseInfo) async {
do {
let (temporaryURL, _) = try await URLSession.shared.download(from: release.downloadURL)
- let downloadsDirectory = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first!
- let destinationURL = downloadsDirectory.appendingPathComponent(release.assetName)
+ let destinationURL = URL.downloadsDirectory.appendingPathComponent(release.assetName)
if FileManager.default.fileExists(atPath: destinationURL.path) {
try? FileManager.default.removeItem(at: destinationURL)
diff --git a/Hotline/State/FilePreviewState.swift b/Hotline/State/FilePreviewState.swift
index 27f8199..ec79f66 100644
--- a/Hotline/State/FilePreviewState.swift
+++ b/Hotline/State/FilePreviewState.swift
@@ -1,8 +1,6 @@
import SwiftUI
import UniformTypeIdentifiers
-// MARK: - Preview Type
-
enum FilePreviewType: Equatable {
case unknown
case image
@@ -13,13 +11,15 @@ enum FilePreviewType: Equatable {
@MainActor
@Observable
final class FilePreviewState {
- // MARK: - Properties
-
+ enum LoadState: Equatable {
+ case unloaded
+ case loading
+ case loaded
+ case failed
+ }
+
let info: PreviewFileInfo
- private var previewClient: HotlineFilePreviewClient?
- private var previewTask: Task<Void, Never>?
-
var state: LoadState = .unloaded
var progress: Double = 0.0
@@ -33,39 +33,35 @@ final class FilePreviewState {
var text: String? = nil
var styledText: NSAttributedString? = nil
-
- // MARK: - Computed Properties
+
+ @ObservationIgnored private var previewClient: HotlineFilePreviewClient?
+ @ObservationIgnored private var previewTask: Task<Void, Never>?
var previewType: FilePreviewType {
- info.previewType
+ self.info.previewType
}
- // MARK: - Initialization
-
init(info: PreviewFileInfo) {
self.info = info
}
- nonisolated deinit {
- // Note: Can't access @MainActor properties from deinit
- // Cleanup will happen when previewClient is deallocated
- }
-
- // MARK: - Public API
+ // MARK: - API
func download() {
// Cancel any existing download
- previewTask?.cancel()
- previewClient?.cleanup()
+ self.previewTask?.cancel()
+ self.previewClient?.cleanup()
let task = Task { @MainActor in
do {
let client = HotlineFilePreviewClient(
- fileName: info.name,
- address: info.address,
- port: UInt16(info.port),
- reference: info.id,
- size: UInt32(info.size)
+ fileName: self.info.name,
+ address: self.info.address,
+ port: UInt16(self.info.port),
+ reference: self.info.id,
+ size: UInt32(self.info.size),
+ fileType: self.info.type,
+ fileCreator: self.info.creator
)
self.previewClient = client
@@ -132,69 +128,58 @@ final class FilePreviewState {
}
func cancel() {
- previewTask?.cancel()
- previewTask = nil
- previewClient?.cancel()
+ self.previewTask?.cancel()
+ self.previewTask = nil
+ self.previewClient?.cancel()
}
func cleanup() {
- previewClient?.cleanup()
- previewClient = nil
- fileURL = nil
- image = nil
- text = nil
- styledText = nil
+ self.previewClient?.cleanup()
+ self.previewClient = nil
+ self.fileURL = nil
+ self.image = nil
+ self.text = nil
+ self.styledText = nil
}
- // MARK: - Private Implementation
+ // MARK: - Utility
- private func loadPreview(from url: URL) {
- guard let data = try? Data(contentsOf: url) else {
- self.state = .failed
- print("FilePreviewState: Failed to read preview data from \(url.path)")
- return
- }
-
- switch self.previewType {
- case .image:
- #if os(iOS)
- self.image = UIImage(data: data)
- #elseif os(macOS)
- self.image = NSImage(data: data)
- #endif
-
- if self.image == nil {
- self.state = .failed
- print("FilePreviewState: Failed to create image from data")
- }
-
- case .text:
- let encoding: UInt = NSString.stringEncoding(for: data, convertedString: nil, usedLossyConversion: nil)
- if encoding != 0 {
- self.text = String(data: data, encoding: String.Encoding(rawValue: encoding))
- } else {
- self.text = String(data: data, encoding: .utf8)
- }
-
- if self.text == nil {
- self.state = .failed
- print("FilePreviewState: Failed to decode text data")
- }
-
- case .unknown:
- print("FilePreviewState: Unknown preview type for \(info.name)")
- break
- }
- }
-}
-
-// MARK: - Load State
-
-extension FilePreviewState {
- enum LoadState: Equatable {
- case unloaded
- case loading
- case loaded
- case failed
- }
+// private func loadPreview(from url: URL) {
+// guard let data = try? Data(contentsOf: url) else {
+// self.state = .failed
+// print("FilePreviewState: Failed to read preview data from \(url.path)")
+// return
+// }
+//
+// switch self.previewType {
+// case .image:
+// #if os(iOS)
+// self.image = UIImage(data: data)
+// #elseif os(macOS)
+// self.image = NSImage(data: data)
+// #endif
+//
+// if self.image == nil {
+// self.state = .failed
+// print("FilePreviewState: Failed to create image from data")
+// }
+//
+// case .text:
+// let encoding: UInt = NSString.stringEncoding(for: data, convertedString: nil, usedLossyConversion: nil)
+// if encoding != 0 {
+// self.text = String(data: data, encoding: String.Encoding(rawValue: encoding))
+// } else {
+// self.text = String(data: data, encoding: .utf8)
+// }
+//
+// if self.text == nil {
+// self.state = .failed
+// print("FilePreviewState: Failed to decode text data")
+// }
+//
+// case .unknown:
+// print("FilePreviewState: Unknown preview type for \(info.name)")
+// break
+// }
+// }
}
diff --git a/Hotline/State/HotlineState.swift b/Hotline/State/HotlineState.swift
index e80571a..f814818 100644
--- a/Hotline/State/HotlineState.swift
+++ b/Hotline/State/HotlineState.swift
@@ -252,7 +252,7 @@ class HotlineState: Equatable {
// MARK: - Private State
- @ObservationIgnored private var client: HotlineClientNew?
+ @ObservationIgnored private var client: HotlineClient?
@ObservationIgnored private var eventTask: Task<Void, Never>?
@ObservationIgnored private var chatSessionKey: ChatStore.SessionKey?
@ObservationIgnored private var restoredChatSessionKey: ChatStore.SessionKey?
@@ -308,13 +308,13 @@ class HotlineState: Equatable {
iconID: UInt16(iconID)
)
- print("HotlineState.login(): Calling HotlineClientNew.connect()...")
- let client = try await HotlineClientNew.connect(
+ print("HotlineState.login(): Calling HotlineClient.connect()...")
+ let client = try await HotlineClient.connect(
host: server.address,
port: UInt16(server.port),
login: loginInfo
)
- print("HotlineState.login(): HotlineClientNew.connect() returned")
+ print("HotlineState.login(): HotlineClient.connect() returned")
self.client = client
print("HotlineState.login(): Client stored")
@@ -865,7 +865,7 @@ class HotlineState: Equatable {
/// - progressCallback: Optional callback for progress updates (receives TransferInfo and progress 0.0-1.0)
/// - callback: Optional completion callback (receives TransferInfo and final file URL)
@MainActor
- func downloadFileNew(_ fileName: String, path: [String], to destination: URL? = nil, progress progressCallback: ((TransferInfo) -> Void)? = nil, complete callback: ((TransferInfo) -> Void)? = nil) {
+ func downloadFile(_ fileName: String, path: [String], to destination: URL? = nil, progress progressCallback: ((TransferInfo) -> Void)? = nil, complete callback: ((TransferInfo) -> Void)? = nil) {
guard let client = self.client else { return }
var fullPath: [String] = []
@@ -975,7 +975,7 @@ class HotlineState: Equatable {
/// - itemProgressCallback: Optional callback for per-item updates (receives TransferInfo with current file info)
/// - callback: Optional completion callback (receives TransferInfo and final folder URL)
@MainActor
- func downloadFolderNew(
+ func downloadFolder(
_ folderName: String,
path: [String],
to destination: URL? = nil,
@@ -1018,7 +1018,7 @@ class HotlineState: Equatable {
AppState.shared.addTransfer(transfer)
// Create download client
- let downloadClient = HotlineFolderDownloadClientNew(
+ let downloadClient = HotlineFolderDownloadClient(
address: address,
port: UInt16(port),
reference: referenceNumber,
@@ -1091,7 +1091,7 @@ class HotlineState: Equatable {
}
}
- /// Modern async/await folder upload using HotlineFolderUploadClientNew
+ /// Upload a folder to the server.
///
/// - Parameters:
/// - folderURL: URL to the folder on disk to upload
@@ -1155,7 +1155,7 @@ class HotlineState: Equatable {
print("HotlineState: Got folder upload reference: \(referenceNumber)")
// Create upload client
- guard let uploadClient = HotlineFolderUploadClientNew(
+ guard let uploadClient = HotlineFolderUploadClient(
folderURL: folderURL,
address: address,
port: UInt16(port),
@@ -1346,9 +1346,9 @@ class HotlineState: Equatable {
}
func setFileInfo(fileName: String, path filePath: [String], fileNewName: String?, comment: String?, encoding: String.Encoding = .utf8) {
- // TODO: Implement setFileInfo in HotlineClientNew
+ // TODO: Implement setFileInfo in HotlineClient
// This method updates file metadata (name and/or comment)
- print("setFileInfo not yet implemented in HotlineState/HotlineClientNew")
+ print("setFileInfo not yet implemented in HotlineState/HotlineClient")
}
@MainActor
diff --git a/Hotline/State/ServerState.swift b/Hotline/State/ServerState.swift
index 805672d..5913bf5 100644
--- a/Hotline/State/ServerState.swift
+++ b/Hotline/State/ServerState.swift
@@ -29,7 +29,7 @@ enum ServerNavigationType: Identifiable, Hashable, Equatable {
case .files:
return "Files"
case .accounts:
- return "Admin"
+ return "Accounts"
case .user(let userID):
return String(userID)
}