eleven / ocho Public

ios: drop pull-to-refresh on the chat list — the instance socket keeps it live, and it reloads on open, switch and foreground (#559)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 7447de27225819f484b04d4d3ae324623563f586 parent 19b148f
2 files changed, +1 −18
  • ios/LChat/Views/ThreadListCollection.swift +0 −14
  • ios/LChat/Views/ThreadListView.swift +1 −4
diff --git a/ios/LChat/Views/ThreadListCollection.swift b/ios/LChat/Views/ThreadListCollection.swift
index c613572..08ef48d 100644
--- a/ios/LChat/Views/ThreadListCollection.swift
+++ b/ios/LChat/Views/ThreadListCollection.swift
@@ -19,7 +19,6 @@ struct ThreadListCollection: UIViewControllerRepresentable {
var onClose: (ChatThread) -> Void
var onPin: (ChatThread) -> Void
var onToggleUnread: (ChatThread) -> Void
- var onRefresh: () async -> Void
func makeUIViewController(context: Context) -> ThreadListController { ThreadListController() }
@@ -28,7 +27,6 @@ struct ThreadListCollection: UIViewControllerRepresentable {
vc.onClose = onClose
vc.onPin = onPin
vc.onToggleUnread = onToggleUnread
- vc.onRefresh = onRefresh
vc.apply(threads)
}
}
@@ -40,7 +38,6 @@ final class ThreadListController: UICollectionViewController {
var onClose: ((ChatThread) -> Void)?
var onPin: ((ChatThread) -> Void)?
var onToggleUnread: ((ChatThread) -> Void)?
- var onRefresh: (() async -> Void)?
private var threadsByID: [String: ChatThread] = [:]
private var latestThreads: [ChatThread] = []
@@ -114,10 +111,6 @@ final class ThreadListController: UICollectionViewController {
cv.dequeueConfiguredReusableCell(using: cell, for: indexPath, item: id)
}
- let refresh = UIRefreshControl()
- refresh.addTarget(self, action: #selector(handleRefresh), for: .valueChanged)
- collectionView.refreshControl = refresh
-
apply(latestThreads) // data set before the view loaded
}
@@ -150,13 +143,6 @@ final class ThreadListController: UICollectionViewController {
top.setContentScrollView(collectionView, for: .top)
}
- @objc private func handleRefresh() {
- Task { @MainActor in
- await onRefresh?()
- collectionView.refreshControl?.endRefreshing()
- }
- }
-
func apply(_ threads: [ChatThread]) {
latestThreads = threads
guard isViewLoaded, dataSource != nil else { return } // deferred to viewDidLoad
diff --git a/ios/LChat/Views/ThreadListView.swift b/ios/LChat/Views/ThreadListView.swift
index d01022c..29e5d46 100644
--- a/ios/LChat/Views/ThreadListView.swift
+++ b/ios/LChat/Views/ThreadListView.swift
@@ -76,8 +76,7 @@ struct ThreadListView: View {
onSelect: { path.append($0) },
onClose: { store.setHidden($0, true) },
onPin: { store.setPinned($0, !$0.pinned) },
- onToggleUnread: { $0.unread ? store.markRead($0) : store.markUnread($0) },
- onRefresh: { await load() }
+ onToggleUnread: { $0.unread ? store.markRead($0) : store.markUnread($0) }
)
// Extend under the nav bar (and home indicator) so the list scrolls
// *behind* the frosted bar; the collection view's automatic content
@@ -281,8 +280,6 @@ struct ThreadListView: View {
.navigationDestination(for: String.self) { id in
ThreadDestination(store: store, id: id, path: $path)
}
- // Pull-to-refresh lives on the UIKit collection view (ThreadListCollection),
- // not SwiftUI's .refreshable, since the scroll view is now UIKit's.
// Keyed on the instance: when the store swaps in place (switching server),
// SwiftUI reuses this view, so an un-keyed .task would not re-fire and the new
// server's chats would never load.