Skip to content

Commit 9966694

Browse files
feat: re-implement selection stickines
1 parent b2d10f3 commit 9966694

File tree

1 file changed

+40
-5
lines changed

1 file changed

+40
-5
lines changed

Bulkhead/UI/ContentView.swift

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,14 @@ struct ContentView: View {
3232
let appEnv: ApplicationEnvironment
3333
@Binding var selectedTab: MainTabs
3434
@Environment(\.colorScheme) private var colorScheme
35-
@State private var selectedContainer: DockerContainer?
36-
@State private var selectedImage: DockerImage?
3735
@FocusState<ListViewFocusTarget?>.Binding var focusState: ListViewFocusTarget?
3836

37+
@State private var selectedContainer: DockerContainer?
38+
@State private var lastContainer: DockerContainer? = nil
3939
@State private var containerSearchText = ""
40+
41+
@State private var selectedImage: DockerImage?
42+
@State private var lastImage: DockerImage? = nil
4043
@State private var imageSearchText = ""
4144

4245
var filteredContainers: [DockerContainer] {
@@ -88,14 +91,23 @@ struct ContentView: View {
8891
options: nil
8992
)
9093

91-
List(filteredContainers, selection: $selectedContainer) { container in
94+
List(filteredContainers, id: \.self, selection: $selectedContainer) { container in
9295
NavigationLink {
9396
ContainerDetailView(container: container, appEnv: appEnv)
9497
} label: {
9598
ContainerSummaryView(container: container, manager: appEnv.manager, appEnv: appEnv)
9699
.focused($focusState, equals: .item(container))
97100
}
98101
}
102+
.onChange(of: publication.containers) { _, n in
103+
guard selectedContainer == nil && lastContainer == nil else { return }
104+
if let firstContainer = filteredContainers.first {
105+
DispatchQueue.main.async {
106+
selectedContainer = firstContainer
107+
}
108+
}
109+
}
110+
99111
}
100112
.padding(4)
101113
.tabItem {
@@ -112,19 +124,41 @@ struct ContentView: View {
112124
options: nil
113125
)
114126

115-
List(filteredImages, selection: $selectedImage) { image in
127+
List(filteredImages, id: \.self, selection: $selectedImage) { image in
116128
NavigationLink {
117129
ImageDetailView(image: image, appEnv: appEnv)
118130
.focused($focusState, equals: .item(image))
119131
} label: {
120132
ImageSummaryView(image: image)
121133
}
122134
}
135+
.onChange(of: publication.images) { _, n in
136+
guard selectedImage == nil && lastImage == nil else { return }
137+
if let firstImage = filteredImages.first {
138+
DispatchQueue.main.async {
139+
selectedImage = firstImage
140+
}
141+
}
142+
}
143+
123144
}
124145
.tabItem {
125146
Label("Images", systemImage: "photo.stack.fill")
126147
}
127148
.tag(MainTabs.images)
149+
.onChange(of: selectedTab) { _, newTab in
150+
DispatchQueue.main.async {
151+
if newTab == .containers {
152+
lastImage = selectedImage
153+
selectedContainer = lastContainer ?? publication.containers.first
154+
selectedImage = nil
155+
} else if newTab == .images {
156+
lastContainer = selectedContainer
157+
selectedImage = lastImage ?? publication.images.first
158+
selectedContainer = nil
159+
}
160+
}
161+
}
128162
}
129163
} detail: {
130164
Text("Select an object")
@@ -134,6 +168,7 @@ struct ContentView: View {
134168
.onKeyPress(
135169
.escape,
136170
action: {
171+
.onKeyPress(.escape) {
137172
if focusState == .search {
138173
if selectedTab == .containers {
139174
containerSearchText = ""
@@ -143,6 +178,6 @@ struct ContentView: View {
143178
return .handled
144179
}
145180
return .ignored
146-
})
181+
}
147182
}
148183
}

0 commit comments

Comments
 (0)