diff --git a/Packages/Timeline/Sources/Timeline/TimelineView.swift b/Packages/Timeline/Sources/Timeline/TimelineView.swift index 836678eb..02036b19 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineView.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineView.swift @@ -64,6 +64,10 @@ public struct TimelineView: View { .scrollContentBackground(.hidden) .background(theme.primaryBackgroundColor) #endif + .searchable(text: $viewModel.searchQuery, + isPresented: $viewModel.isSearchPresented, + placement: .navigationBarDrawer(displayMode: .automatic), + prompt: Text("Search")) .introspect(.list, on: .iOS(.v17)) { (collectionView: UICollectionView) in DispatchQueue.main.async { self.collectionView = collectionView diff --git a/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift b/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift index 02975522..8d1fcf2a 100644 --- a/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift +++ b/Packages/Timeline/Sources/Timeline/TimelineViewModel.swift @@ -77,6 +77,28 @@ import SwiftUI var isTimelineVisible: Bool = false let pendingStatusesObserver: PendingStatusesObserver = .init() var scrollToIndexAnimated: Bool = false + + var searchQuery: String = "" { + didSet { + Task { + let statuses = await datasource.get().filter { status in + status.content.asRawText.contains(searchQuery) + } + statusesState = .display(statuses: statuses, nextPageState: .none) + } + } + } + + var isSearchPresented: Bool = false { + didSet { + if !isSearchPresented { + Task { + let statuses = await datasource.get() + statusesState = .display(statuses: statuses, nextPageState: .hasNextPage) + } + } + } + } init() { pendingStatusesObserver.scrollToIndex = { [weak self] index in