Fix SFTP status bar transfer direction
This commit is contained in:
1 parent
781dbcdfc9
commit
42660095a5
2 files changed
+95
-4
No files matched your search
@@ -33,6 +33,24 @@ nonisolated enum StatusBarPresentation {
|
||||
}
|
||||
}
|
||||
|
||||
/// The direction worth showing inside the active transfer progress ring.
|
||||
///
|
||||
/// Only work that is actually moving bytes participates. Queued and historical
|
||||
/// transfers still contribute to the transfer center's existing counts and
|
||||
/// state, but they must not make a running upload or download look mixed.
|
||||
nonisolated enum StatusBarTransferPresentation {
|
||||
static func runningDirectionSymbol(for transfers: [SFTPTransfer]) -> String {
|
||||
let directions = Set(
|
||||
transfers.lazy
|
||||
.filter { $0.state == .running }
|
||||
.map(\.direction)
|
||||
)
|
||||
if directions == [.upload] { return "arrow.up" }
|
||||
if directions == [.download] { return "arrow.down" }
|
||||
return "arrow.up.arrow.down"
|
||||
}
|
||||
}
|
||||
|
||||
/// Focused-session context and app-wide transfers, as one floating capsule.
|
||||
///
|
||||
/// It used to be a docked strip with a hairline above it, which read as a piece
|
||||
@@ -179,8 +197,11 @@ struct StatusBarView: View {
|
||||
height: Metrics.Sidebar.statusDot
|
||||
)
|
||||
case .transfers:
|
||||
TransferGlyph(summary: app.sftpTransfers.summary)
|
||||
.frame(width: 18, height: 18)
|
||||
TransferGlyph(
|
||||
summary: app.sftpTransfers.summary,
|
||||
transfers: app.sftpTransfers.sftpTransfers
|
||||
)
|
||||
.frame(width: 18, height: 18)
|
||||
}
|
||||
}
|
||||
.frame(
|
||||
@@ -372,6 +393,7 @@ private struct StatusBarPathLabel: View {
|
||||
/// front of it.
|
||||
private struct TransferGlyph: View {
|
||||
let summary: SFTPTransferSummary
|
||||
let transfers: [SFTPTransfer]
|
||||
|
||||
@ViewBuilder
|
||||
var body: some View {
|
||||
@@ -389,7 +411,7 @@ private struct TransferGlyph: View {
|
||||
} else {
|
||||
ProgressView().controlSize(.mini)
|
||||
}
|
||||
Image(systemName: "arrow.up")
|
||||
Image(systemName: StatusBarTransferPresentation.runningDirectionSymbol(for: transfers))
|
||||
.font(.system(size: 8, weight: .bold))
|
||||
}
|
||||
} else if summary.failedCount > 0 {
|
||||
@@ -414,7 +436,8 @@ private struct TransferCenterButton: View {
|
||||
isPresented.toggle()
|
||||
} label: {
|
||||
HStack(spacing: Metrics.Space.xs) {
|
||||
TransferGlyph(summary: summaryValue).frame(width: 18, height: 18)
|
||||
TransferGlyph(summary: summaryValue, transfers: coordinator.sftpTransfers)
|
||||
.frame(width: 18, height: 18)
|
||||
if summaryValue.activeCount > 0 {
|
||||
Text(summaryValue.activeCount, format: .number)
|
||||
.monospacedDigit()
|
||||
|
||||
@@ -82,4 +82,72 @@ struct StatusBarPresentationTests {
|
||||
)
|
||||
#expect(Metrics.StatusBar.overlayClearance > Metrics.StatusBar.height)
|
||||
}
|
||||
|
||||
@Test
|
||||
func runningUploadsUseTheUploadSymbol() {
|
||||
let transfers = [
|
||||
transfer(direction: .upload, state: .running),
|
||||
transfer(direction: .upload, state: .running),
|
||||
]
|
||||
|
||||
#expect(StatusBarTransferPresentation.runningDirectionSymbol(for: transfers) == "arrow.up")
|
||||
}
|
||||
|
||||
@Test
|
||||
func runningDownloadsUseTheDownloadSymbol() {
|
||||
let transfers = [
|
||||
transfer(direction: .download, state: .running),
|
||||
transfer(direction: .download, state: .running),
|
||||
]
|
||||
|
||||
#expect(StatusBarTransferPresentation.runningDirectionSymbol(for: transfers) == "arrow.down")
|
||||
}
|
||||
|
||||
@Test
|
||||
func copiesAndMixedDirectionsUseTheBidirectionalSymbol() {
|
||||
#expect(
|
||||
StatusBarTransferPresentation.runningDirectionSymbol(
|
||||
for: [transfer(direction: .copy, state: .running)]
|
||||
) == "arrow.up.arrow.down"
|
||||
)
|
||||
#expect(
|
||||
StatusBarTransferPresentation.runningDirectionSymbol(
|
||||
for: [
|
||||
transfer(direction: .upload, state: .running),
|
||||
transfer(direction: .download, state: .running),
|
||||
]
|
||||
) == "arrow.up.arrow.down"
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
func onlyRunningTransfersChooseTheDirectionSymbol() {
|
||||
let transfers = [
|
||||
transfer(direction: .upload, state: .running),
|
||||
transfer(direction: .download, state: .queued),
|
||||
transfer(direction: .download, state: .paused),
|
||||
transfer(direction: .download, state: .completed),
|
||||
transfer(direction: .download, state: .cancelled),
|
||||
transfer(direction: .download, state: .failed("Offline")),
|
||||
]
|
||||
|
||||
#expect(StatusBarTransferPresentation.runningDirectionSymbol(for: transfers) == "arrow.up")
|
||||
#expect(
|
||||
StatusBarTransferPresentation.runningDirectionSymbol(
|
||||
for: [transfer(direction: .download, state: .queued)]
|
||||
) == "arrow.up.arrow.down"
|
||||
)
|
||||
}
|
||||
|
||||
private func transfer(
|
||||
direction: SFTPTransfer.Direction,
|
||||
state: SFTPTransfer.State
|
||||
) -> SFTPTransfer {
|
||||
SFTPTransfer(
|
||||
direction: direction,
|
||||
localPath: "/tmp/file.txt",
|
||||
remotePath: "/srv/file.txt",
|
||||
state: state
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user