aboutsummaryrefslogtreecommitdiff
path: root/Hotline
diff options
context:
space:
mode:
Diffstat (limited to 'Hotline')
-rw-r--r--Hotline/Models/Hotline.swift25
-rw-r--r--Hotline/macOS/FilesView.swift64
-rw-r--r--Hotline/macOS/TrackerView.swift3
3 files changed, 64 insertions, 28 deletions
diff --git a/Hotline/Models/Hotline.swift b/Hotline/Models/Hotline.swift
index b93fb55..786fb0c 100644
--- a/Hotline/Models/Hotline.swift
+++ b/Hotline/Models/Hotline.swift
@@ -1,10 +1,10 @@
import SwiftUI
struct FileSearchConfig: Equatable {
- var initialBurstCount: Int = 8
- var initialDelay: TimeInterval = 0.05
- var backoffMultiplier: Double = 1.6
- var maxDelay: TimeInterval = 1.5
+ var initialBurstCount: Int = 15
+ var initialDelay: TimeInterval = 0.02
+ var backoffMultiplier: Double = 1.1
+ var maxDelay: TimeInterval = 1.3
var maxDepth: Int = 40
var loopRepetitionLimit: Int = 4
}
@@ -160,6 +160,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega
var fileSearchQuery: String = ""
var fileSearchConfig = FileSearchConfig()
var fileSearchScannedFolders: Int = 0
+ var fileSearchCurrentPath: [String]? = nil
@ObservationIgnored private var fileSearchSession: FileSearchSession? = nil
@ObservationIgnored private var fileSearchResultKeys: Set<String> = []
var news: [NewsInfo] = []
@@ -335,6 +336,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega
fileSearchQuery = trimmed
fileSearchStatus = .searching(processed: 0, pending: 0)
fileSearchScannedFolders = 0
+ fileSearchCurrentPath = []
let session = FileSearchSession(hotline: self, query: trimmed, config: fileSearchConfig)
fileSearchSession = session
@@ -348,12 +350,14 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega
resetFileSearchState()
} else if !fileSearchResults.isEmpty {
fileSearchStatus = .cancelled(processed: fileSearchScannedFolders)
+ fileSearchCurrentPath = nil
}
return
}
session.cancel()
fileSearchSession = nil
+ fileSearchCurrentPath = nil
if clearResults {
resetFileSearchState()
}
@@ -383,6 +387,14 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega
fileSearchStatus = .searching(processed: processed, pending: pending)
}
+ @MainActor fileprivate func searchSession(_ session: FileSearchSession, didFocusOn path: [String]) {
+ guard fileSearchSession === session else {
+ return
+ }
+
+ fileSearchCurrentPath = path
+ }
+
@MainActor fileprivate func searchSessionDidFinish(_ session: FileSearchSession, processed: Int, pending: Int, completed: Bool) {
guard fileSearchSession === session else {
return
@@ -390,6 +402,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega
fileSearchScannedFolders = processed
fileSearchSession = nil
+ fileSearchCurrentPath = nil
if completed {
fileSearchStatus = .completed(processed: processed)
} else {
@@ -403,6 +416,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega
fileSearchStatus = .idle
fileSearchQuery = ""
fileSearchScannedFolders = 0
+ fileSearchCurrentPath = nil
}
private func searchPathKey(for path: [String]) -> String {
@@ -1315,11 +1329,13 @@ final class FileSearchSession {
await Task.yield()
if !hotline.filesLoaded {
+ hotline.searchSession(self, didFocusOn: [])
let rootFiles = await hotline.getFileList(path: [], suppressErrors: true)
processedCount = max(processedCount, 1)
processListing(rootFiles, depth: 0)
}
else {
+ hotline.searchSession(self, didFocusOn: [])
processedCount = max(processedCount, 1)
processListing(hotline.files, depth: 0)
}
@@ -1333,6 +1349,7 @@ final class FileSearchSession {
continue
}
+ hotline.searchSession(self, didFocusOn: task.path)
visited.insert(pathKey(for: task.path))
let children = await hotline.getFileList(path: task.path, suppressErrors: true)
diff --git a/Hotline/macOS/FilesView.swift b/Hotline/macOS/FilesView.swift
index 206e0a4..4498dc9 100644
--- a/Hotline/macOS/FilesView.swift
+++ b/Hotline/macOS/FilesView.swift
@@ -255,6 +255,16 @@ struct FilesView: View {
return nil
}
}
+
+ private var searchStatusPath: String? {
+ guard let path = model.fileSearchCurrentPath else {
+ return nil
+ }
+ if path.isEmpty {
+ return "/"
+ }
+ return "/" + path.joined(separator: "/") + "/"
+ }
private func openPreviewWindow(_ previewInfo: PreviewFileInfo) {
switch previewInfo.previewType {
@@ -529,56 +539,64 @@ struct FilesView: View {
}
.safeAreaInset(edge: .top) {
if isShowingSearchResults, let message = searchStatusMessage {
- HStack {
- Spacer()
-
+ HStack(alignment: .center, spacing: 6) {
if case .searching(_, _) = model.fileSearchStatus {
ProgressView()
.controlSize(.small)
- .tint(.red)
+ .accentColor(.white)
+ .tint(.white)
}
else if case .completed = model.fileSearchStatus {
Image(systemName: "checkmark.circle.fill")
.resizable()
- .symbolRenderingMode(.palette)
- .foregroundStyle(.white, .fileComplete)
+ .symbolRenderingMode(.monochrome)
+ .foregroundStyle(.white)
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
}
else if case .failed = model.fileSearchStatus {
Image(systemName: "exclamationmark.triangle.fill")
.resizable()
- .symbolRenderingMode(.multicolor)
+ .symbolRenderingMode(.monochrome)
+ .foregroundStyle(.white)
.aspectRatio(contentMode: .fit)
.frame(width: 16, height: 16)
}
Text(message)
+ .lineLimit(1)
.font(.body)
.foregroundStyle(.white)
Spacer()
+
+ if let pathMessage = searchStatusPath {
+ Text(pathMessage)
+ .lineLimit(1)
+ .truncationMode(.tail)
+ .font(.footnote)
+// .fontWeight(.semibold)
+ .foregroundStyle(.white)
+ .opacity(0.5)
+ .padding(.top, 2)
+ }
}
-// .overlay(alignment: .leading) {
-// Button {
-// model.cancelFileSearch(clearResults: true)
-// } label: {
-// Image(systemName: "xmark.circle.fill")
-// .resizable()
-// .scaledToFit()
-// .foregroundStyle(.white)
-// .opacity(0.8)
-// }
-// .buttonStyle(.plain)
-// }
- .padding(.horizontal, 8)
- .padding(.leading, 4)
+ .padding(.trailing, 14)
+ .padding(.leading, 8)
.padding(.vertical, 8)
.background {
- Color(nsColor: .controlAccentColor)
- .clipShape(.capsule(style: .continuous))
+ Group {
+ if case .completed = model.fileSearchStatus {
+ Color.fileComplete
+ }
+ else {
+ Color(nsColor: .controlAccentColor)
+ }
+ }
+ .clipShape(.capsule(style: .continuous))
}
.padding(.horizontal, 8)
+ .padding(.top, 8)
}
}
}
diff --git a/Hotline/macOS/TrackerView.swift b/Hotline/macOS/TrackerView.swift
index 83a56b8..c14f982 100644
--- a/Hotline/macOS/TrackerView.swift
+++ b/Hotline/macOS/TrackerView.swift
@@ -416,8 +416,9 @@ struct TrackerView: View {
// Not expanded, expand it (which also fetches)
self.setExpanded(true, for: bookmark)
}
+ return
}
- return
+ break
default:
break
}