Skip to content

Commit c895c54

Browse files
committed
refactor(ui): align welcome connection row with native macOS list patterns
1 parent 40ee8a7 commit c895c54

1 file changed

Lines changed: 69 additions & 64 deletions

File tree

TablePro/Views/Connection/WelcomeConnectionRow.swift

Lines changed: 69 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -15,89 +15,94 @@ struct WelcomeConnectionRow: View {
1515
return TagStorage.shared.tag(for: tagId)
1616
}
1717

18+
private var sshEnabled: Bool {
19+
connection.resolvedSSHConfig.enabled
20+
}
21+
22+
private var showsLocalOnly: Bool {
23+
connection.localOnly && !connection.isSample
24+
}
25+
1826
var body: some View {
19-
HStack(spacing: 12) {
27+
HStack {
2028
connection.type.iconImage
2129
.renderingMode(.template)
22-
.font(.system(size: 16))
30+
.font(.title3)
2331
.foregroundStyle(connection.displayColor)
24-
.frame(
25-
width: 16,
26-
height: 16
27-
)
28-
29-
VStack(alignment: .leading, spacing: 2) {
30-
HStack(spacing: 6) {
31-
Text(connection.name)
32-
.font(.body.weight(.medium))
33-
.foregroundStyle(.primary)
34-
35-
if let tag = displayTag {
36-
Text(tag.name)
37-
.font(.system(size: 9))
38-
.foregroundStyle(tag.color.color)
39-
.padding(.horizontal, 4)
40-
.padding(.vertical, 2)
41-
.background(
42-
RoundedRectangle(cornerRadius: 4).fill(
43-
tag.color.color.opacity(0.15)))
44-
}
45-
46-
if connection.isSample {
47-
Text(String(localized: "Sample"))
48-
.font(.system(size: 9, weight: .semibold))
49-
.foregroundStyle(Color.accentColor)
50-
.padding(.horizontal, 5)
51-
.padding(.vertical, 2)
52-
.background(
53-
RoundedRectangle(cornerRadius: 4)
54-
.fill(Color.accentColor.opacity(0.15))
55-
)
56-
.help(String(localized: "Bundled sample database"))
57-
}
58-
59-
if connection.resolvedSSHConfig.enabled {
60-
Image(systemName: "lock.shield")
61-
.font(.system(size: 10))
62-
.foregroundStyle(.secondary)
63-
.help(sshTunnelTooltip)
64-
.accessibilityLabel(String(localized: "SSH tunnel"))
65-
}
66-
67-
if connection.localOnly && !connection.isSample {
68-
Image(systemName: "icloud.slash")
69-
.font(.system(size: 9))
70-
.foregroundStyle(.secondary)
71-
.help(String(localized: "Local only - not synced to iCloud"))
72-
}
73-
}
32+
.frame(width: 18, height: 18)
7433

75-
Text(connectionSubtitle)
34+
VStack(alignment: .leading, spacing: 1) {
35+
Text(connection.name)
36+
.font(.body)
37+
.foregroundStyle(.primary)
38+
39+
Text(subtitleText)
7640
.font(.subheadline)
7741
.foregroundStyle(.secondary)
7842
.lineLimit(1)
79-
.help(connectionSubtitle)
43+
.truncationMode(.middle)
44+
.help(subtitleText)
8045
}
8146

82-
Spacer()
47+
Spacer(minLength: 8)
48+
49+
trailingAccessories
8350
}
84-
.padding(.vertical, 4)
8551
.contentShape(Rectangle())
86-
.overlay(
87-
DoubleClickDetector { onConnect?() }
88-
)
52+
.overlay(DoubleClickDetector { onConnect?() })
53+
.accessibilityElement(children: .combine)
54+
}
55+
56+
@ViewBuilder
57+
private var trailingAccessories: some View {
58+
HStack(spacing: 8) {
59+
if sshEnabled {
60+
Image(systemName: "lock.fill")
61+
.imageScale(.small)
62+
.foregroundStyle(.tertiary)
63+
.help(sshTunnelTooltip)
64+
.accessibilityLabel(String(localized: "SSH tunnel"))
65+
}
66+
67+
if showsLocalOnly {
68+
Image(systemName: "icloud.slash")
69+
.imageScale(.small)
70+
.foregroundStyle(.tertiary)
71+
.help(String(localized: "Local only, not synced to iCloud"))
72+
.accessibilityLabel(String(localized: "Local only"))
73+
}
74+
75+
if let tag = displayTag {
76+
HStack(spacing: 4) {
77+
Circle()
78+
.fill(tag.color.color)
79+
.frame(width: 8, height: 8)
80+
Text(tag.name)
81+
.font(.caption)
82+
.foregroundStyle(.secondary)
83+
.lineLimit(1)
84+
}
85+
.accessibilityElement(children: .combine)
86+
.accessibilityLabel(String(format: String(localized: "Tag: %@"), tag.name))
87+
}
88+
}
89+
}
90+
91+
private var subtitleText: String {
92+
var components: [String] = [primaryEndpoint]
93+
if connection.isSample {
94+
components.append(String(localized: "Sample"))
95+
}
96+
return components.joined(separator: " · ")
8997
}
9098

91-
private var connectionSubtitle: String {
99+
private var primaryEndpoint: String {
92100
if connection.host.isEmpty {
93101
return connection.database.isEmpty ? connection.type.rawValue : connection.database
94102
}
95103
if let mongoHosts = connection.additionalFields["mongoHosts"], mongoHosts.contains(",") {
96104
let count = mongoHosts.split(separator: ",").count
97-
return String(
98-
format: String(localized: "%@ (+%d more)"),
99-
hostWithOptionalPort, count - 1
100-
)
105+
return String(format: String(localized: "%@ (+%d more)"), hostWithOptionalPort, count - 1)
101106
}
102107
return hostWithOptionalPort
103108
}

0 commit comments

Comments
 (0)