Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Coder-Desktop/Coder-Desktop/Theme.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ enum Theme {
static let appIconWidth: CGFloat = 17
static let appIconHeight: CGFloat = 17
static let appIconSize: CGSize = .init(width: appIconWidth, height: appIconHeight)

static let tableFooterIconSize: CGFloat = 30
}

enum Animation {
Expand Down
30 changes: 23 additions & 7 deletions Coder-Desktop/Coder-Desktop/Views/FileSync/FileSyncConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct FileSyncConfig<VPN: VPNService, FS: FileSyncDaemon>: View {
}
})
.frame(minWidth: 400, minHeight: 200)
.padding(.bottom, 25)
.padding(.bottom, Theme.Size.tableFooterIconSize)
.overlay(alignment: .bottom) {
tableFooter
}
Expand Down Expand Up @@ -121,8 +121,8 @@ struct FileSyncConfig<VPN: VPNService, FS: FileSyncDaemon>: View {
Button {
addingNewSession = true
} label: {
Image(systemName: "plus")
.frame(width: 24, height: 24).help("Create")
FooterIcon(systemName: "plus")
.help("Create")
}.disabled(vpn.menuState.agents.isEmpty)
sessionControls
}
Expand All @@ -139,21 +139,25 @@ struct FileSyncConfig<VPN: VPNService, FS: FileSyncDaemon>: View {
Divider()
Button { Task { await delete(session: selectedSession) } }
label: {
Image(systemName: "minus").frame(width: 24, height: 24).help("Terminate")
FooterIcon(systemName: "minus")
.help("Terminate")
}
Divider()
Button { Task { await pauseResume(session: selectedSession) } }
label: {
if selectedSession.status.isResumable {
Image(systemName: "play").frame(width: 24, height: 24).help("Pause")
FooterIcon(systemName: "play")
.help("Pause")
} else {
Image(systemName: "pause").frame(width: 24, height: 24).help("Resume")
FooterIcon(systemName: "pause")
.help("Resume")
}
}
Divider()
Button { Task { await reset(session: selectedSession) } }
label: {
Image(systemName: "arrow.clockwise").frame(width: 24, height: 24).help("Reset")
FooterIcon(systemName: "arrow.clockwise")
.help("Reset")
}
}
}
Expand Down Expand Up @@ -199,6 +203,18 @@ struct FileSyncConfig<VPN: VPNService, FS: FileSyncDaemon>: View {
}
}

struct FooterIcon: View {
let systemName: String

var body: some View {
Image(systemName: systemName)
.frame(
width: Theme.Size.tableFooterIconSize,
height: Theme.Size.tableFooterIconSize
)
}
}

#if DEBUG
#Preview {
FileSyncConfig<PreviewVPN, PreviewFileSync>()
Expand Down
2 changes: 2 additions & 0 deletions Coder-Desktop/Coder-Desktop/Views/VPN/VPNMenuItem.swift
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,12 @@ struct MenuItemIcons: View {
MenuItemIconButton(systemName: "doc.on.doc", action: copyToClipboard)
.font(.system(size: 9))
.symbolVariant(.fill)
.help("Copy hostname")
MenuItemIconButton(systemName: "globe", action: { openURL(wsURL) })
.contentShape(Rectangle())
.font(.system(size: 12))
.padding(.trailing, Theme.Size.trayMargin)
.help("Open in browser")
}
}

Expand Down
13 changes: 9 additions & 4 deletions Coder-Desktop/VPNLib/Download.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,15 @@ func etag(data: Data) -> String {
}

public enum DownloadError: Error {
case unexpectedStatusCode(Int)
case unexpectedStatusCode(Int, url: String)
case invalidResponse
case networkError(any Error, url: String)
case fileOpError(any Error)

public var description: String {
switch self {
case let .unexpectedStatusCode(code):
"Unexpected HTTP status code: \(code)"
case let .unexpectedStatusCode(code, url):
"Unexpected HTTP status code: \(code) - \(url)"
case let .networkError(error, url):
"Network error: \(url) - \(error.localizedDescription)"
case let .fileOpError(error):
Expand Down Expand Up @@ -232,7 +232,12 @@ extension DownloadManager: URLSessionDownloadDelegate {
}

guard httpResponse.statusCode == 200 else {
continuation.resume(throwing: DownloadError.unexpectedStatusCode(httpResponse.statusCode))
continuation.resume(
throwing: DownloadError.unexpectedStatusCode(
httpResponse.statusCode,
url: httpResponse.url?.absoluteString ?? "Unknown URL"
)
)
return
}

Expand Down
Loading