Skip to content

Commit d19118d

Browse files
authored
fix(ios): P2 HIG polish — search caps, structure refresh, filter confirm, badge contrast, iPad sidebar (#678)
1 parent a28e2f9 commit d19118d

6 files changed

Lines changed: 74 additions & 47 deletions

File tree

TableProMobile/TableProMobile/Views/ConnectionListView.swift

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import TableProSync
99

1010
struct ConnectionListView: View {
1111
@Environment(AppState.self) private var appState
12+
@Environment(\.horizontalSizeClass) private var sizeClass
1213
@State private var showingAddConnection = false
1314
@State private var editingConnection: DatabaseConnection?
1415
@State private var selectedConnectionId: UUID?
@@ -132,6 +133,32 @@ struct ConnectionListView: View {
132133
}
133134
}
134135

136+
@ViewBuilder
137+
private var connectionList: some View {
138+
let list = List(selection: $selectedConnectionId) {
139+
if groupByGroup {
140+
groupedContent
141+
} else {
142+
ForEach(displayedConnections) { connection in
143+
connectionRow(connection)
144+
}
145+
.onMove { source, destination in
146+
var items = displayedConnections
147+
items.move(fromOffsets: source, toOffset: destination)
148+
for index in items.indices {
149+
items[index].sortOrder = index
150+
}
151+
appState.reorderConnections(items)
152+
}
153+
}
154+
}
155+
if sizeClass == .regular {
156+
list.listStyle(.sidebar)
157+
} else {
158+
list.listStyle(.insetGrouped)
159+
}
160+
}
161+
135162
@ViewBuilder
136163
private var sidebar: some View {
137164
if appState.connections.isEmpty && !isSyncing {
@@ -149,24 +176,7 @@ struct ConnectionListView: View {
149176
ProgressView("Syncing from iCloud...")
150177
.frame(maxWidth: .infinity, maxHeight: .infinity)
151178
} else {
152-
List(selection: $selectedConnectionId) {
153-
if groupByGroup {
154-
groupedContent
155-
} else {
156-
ForEach(displayedConnections) { connection in
157-
connectionRow(connection)
158-
}
159-
.onMove { source, destination in
160-
var items = displayedConnections
161-
items.move(fromOffsets: source, toOffset: destination)
162-
for index in items.indices {
163-
items[index].sortOrder = index
164-
}
165-
appState.reorderConnections(items)
166-
}
167-
}
168-
}
169-
.listStyle(.insetGrouped)
179+
connectionList
170180
.overlay {
171181
if !appState.connections.isEmpty && displayedConnections.isEmpty {
172182
ContentUnavailableView(
@@ -403,12 +413,12 @@ private struct ConnectionRow: View {
403413
if let tag {
404414
Text(tag.name)
405415
.font(.caption)
406-
.foregroundStyle(ConnectionColorPicker.swiftUIColor(for: tag.color))
416+
.foregroundStyle(.white)
407417
.padding(.horizontal, 8)
408418
.padding(.vertical, 3)
409419
.background(
410420
Capsule()
411-
.fill(ConnectionColorPicker.swiftUIColor(for: tag.color).opacity(0.15))
421+
.fill(ConnectionColorPicker.swiftUIColor(for: tag.color))
412422
)
413423
}
414424
}

TableProMobile/TableProMobile/Views/DataBrowserView.swift

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ struct DataBrowserView: View {
204204
.navigationTitle(table.name)
205205
.navigationBarTitleDisplayMode(.inline)
206206
.searchable(text: $searchText, prompt: "Search all columns")
207+
.textInputAutocapitalization(.never)
207208
.onSubmit(of: .search) { applySearch() }
208209
.onChange(of: searchText) { oldValue, newValue in
209210
if newValue.isEmpty, !oldValue.isEmpty, hasActiveSearch {
@@ -696,6 +697,7 @@ private struct FilterSheetView: View {
696697

697698
@State private var draft: [TableFilter] = []
698699
@State private var draftLogicMode: FilterLogicMode = .and
700+
@State private var showClearConfirmation = false
699701

700702
private var hasValidFilters: Bool {
701703
draft.contains { $0.isEnabled && $0.isValid }
@@ -763,10 +765,7 @@ private struct FilterSheetView: View {
763765
if !draft.isEmpty {
764766
Section {
765767
Button("Clear All Filters", role: .destructive) {
766-
filters.removeAll()
767-
logicMode = .and
768-
onClear()
769-
dismiss()
768+
showClearConfirmation = true
770769
}
771770
}
772771
}
@@ -791,6 +790,20 @@ private struct FilterSheetView: View {
791790
draft = filters
792791
draftLogicMode = logicMode
793792
}
793+
.confirmationDialog(
794+
String(localized: "Clear All Filters"),
795+
isPresented: $showClearConfirmation,
796+
titleVisibility: .visible
797+
) {
798+
Button(String(localized: "Clear All"), role: .destructive) {
799+
filters.removeAll()
800+
logicMode = .and
801+
onClear()
802+
dismiss()
803+
}
804+
} message: {
805+
Text("All filter conditions will be removed.")
806+
}
794807
}
795808
}
796809
}

TableProMobile/TableProMobile/Views/InsertRowView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ struct InsertRowView: View {
113113
}
114114
}
115115
}
116+
.scrollDismissesKeyboard(.interactively)
116117
.formStyle(.grouped)
117118
.navigationTitle("Insert Row")
118119
.navigationBarTitleDisplayMode(.inline)

TableProMobile/TableProMobile/Views/RowDetailView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ struct RowDetailView: View {
100100
.transition(.move(edge: .bottom).combined(with: .opacity))
101101
}
102102
}
103-
.navigationTitle(String(format: String(localized: "Row %d of %d"), currentIndex + 1, rows.count))
103+
.navigationTitle(table?.name ?? String(format: String(localized: "Row %d of %d"), currentIndex + 1, rows.count))
104104
.navigationBarTitleDisplayMode(.inline)
105105
.toolbar {
106106
ToolbarItem(placement: .topBarTrailing) {

TableProMobile/TableProMobile/Views/StructureView.swift

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,37 +29,39 @@ struct StructureView: View {
2929
@State private var appError: AppError?
3030

3131
var body: some View {
32-
VStack(spacing: 0) {
32+
Group {
33+
if isLoading {
34+
ProgressView("Loading structure...")
35+
.frame(maxWidth: .infinity, maxHeight: .infinity)
36+
} else if let appError {
37+
ErrorView(error: appError) {
38+
await loadStructure()
39+
}
40+
} else {
41+
switch selectedTab {
42+
case .columns:
43+
columnsTab
44+
case .indexes:
45+
indexesTab
46+
case .foreignKeys:
47+
foreignKeysTab
48+
}
49+
}
50+
}
51+
.safeAreaInset(edge: .top) {
3352
Picker("Section", selection: $selectedTab) {
3453
ForEach(Tab.allCases, id: \.self) { tab in
3554
Text(tab.rawValue).tag(tab)
3655
}
3756
}
3857
.pickerStyle(.segmented)
39-
.padding()
40-
41-
Group {
42-
if isLoading {
43-
ProgressView("Loading structure...")
44-
.frame(maxWidth: .infinity, maxHeight: .infinity)
45-
} else if let appError {
46-
ErrorView(error: appError) {
47-
await loadStructure()
48-
}
49-
} else {
50-
switch selectedTab {
51-
case .columns:
52-
columnsTab
53-
case .indexes:
54-
indexesTab
55-
case .foreignKeys:
56-
foreignKeysTab
57-
}
58-
}
59-
}
58+
.padding(.horizontal)
59+
.padding(.vertical, 8)
60+
.background(.bar)
6061
}
6162
.navigationTitle(table.name)
6263
.navigationBarTitleDisplayMode(.inline)
64+
.refreshable { await loadStructure() }
6365
.task { await loadStructure() }
6466
}
6567

TableProMobile/TableProMobile/Views/TableListView.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ struct TableListView: View {
101101
}
102102
.listStyle(.insetGrouped)
103103
.searchable(text: $searchText, prompt: "Search tables")
104+
.textInputAutocapitalization(.never)
104105
.refreshable {
105106
await onRefresh?()
106107
}

0 commit comments

Comments
 (0)