Skip to content

Commit

Permalink
Search: Display posts search when pressing enter
Browse files Browse the repository at this point in the history
  • Loading branch information
Dimillian committed May 16, 2021
1 parent fc10e4d commit 9378834
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 33 deletions.
3 changes: 3 additions & 0 deletions Packages/Backend/Sources/Backend/Network/Endpoint.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ public enum Endpoint {
case subredditAbout(name: String)
case subscribe
case searchSubreddit
case search
case comments(name: String, id: String)
case accessToken
case me, mineSubscriptions, mineMulti
Expand Down Expand Up @@ -62,6 +63,8 @@ public enum Endpoint {
return "user/\(username)/comments"
case .trendingSubreddits:
return "api/trending_subreddits"
case .search:
return "search"
}
}
}
4 changes: 2 additions & 2 deletions RedditOs.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 0.4.3;
MARKETING_VERSION = 0.4.4;
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.curiosity;
PRODUCT_NAME = Curiosity;
SWIFT_VERSION = 5.0;
Expand All @@ -676,7 +676,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 11.0;
MARKETING_VERSION = 0.4.3;
MARKETING_VERSION = 0.4.4;
PRODUCT_BUNDLE_IDENTIFIER = com.thomasricouard.curiosity;
PRODUCT_NAME = Curiosity;
SWIFT_VERSION = 5.0;
Expand Down
5 changes: 3 additions & 2 deletions RedditOs/Features/Post/PostDetailToolbar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ struct PostDetailToolbar: ToolbarContent {
SharingView(url: shareURL)
Spacer()
if uiState.displayToolbarSearchBar {
ToolbarSearchBar(isPopoverEnabled: true)
.frame(width: 300)
ToolbarSearchBar(isPopoverEnabled: true,
onCommit: {}, onCancel: {})
.frame(width: 300)
}
}
}
Expand Down
59 changes: 42 additions & 17 deletions RedditOs/Features/Search/SearchMainContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ struct SearchMainContentView: View {
@EnvironmentObject private var uiState: UIState
@EnvironmentObject private var searchState: SearchState

enum ResultsMode {
case autocomplete, posts
}

@State private var resultsDisplayMode = ResultsMode.autocomplete

var body: some View {
VStack(alignment: .leading) {
if let route = uiState.searchRoute {
HStack {
Button {
uiState.searchRoute = nil
resultsDisplayMode = .autocomplete
} label: {
Text("Back")
}
Expand All @@ -27,24 +34,14 @@ struct SearchMainContentView: View {
.frame(height: 50)
route.makeView()
} else {
ToolbarSearchBar(isPopoverEnabled: false)
.padding()
ToolbarSearchBar(isPopoverEnabled: false, onCommit: {
resultsDisplayMode = .posts
}, onCancel: {
resultsDisplayMode = .autocomplete
})
.padding()
List {
if searchState.searchText.isEmpty {
if let trending = searchState.trending {
Section(header: Label("Trending", systemImage: "chart.bar.fill")) {
ForEach(trending.subredditNames, id: \.self) { subreddit in
Text(subreddit)
.padding(.vertical, 4)
.onTapGesture {
uiState.searchRoute = .subreddit(subreddit: subreddit)
}
}
}
}
} else {
GlobalSearchPopoverView()
}
resultsView
}
.listStyle(PlainListStyle())
.padding(.horizontal)
Expand All @@ -55,6 +52,34 @@ struct SearchMainContentView: View {
searchState.fetchTrending()
}
}

@ViewBuilder
private var resultsView: some View {
switch resultsDisplayMode {
case .autocomplete:
if searchState.searchText.isEmpty {
if let trending = searchState.trending {
Section(header: Label("Trending", systemImage: "chart.bar.fill")) {
ForEach(trending.subredditNames, id: \.self) { subreddit in
Text(subreddit)
.padding(.vertical, 4)
.onTapGesture {
uiState.searchRoute = .subreddit(subreddit: subreddit)
}
}
}
}
} else {
GlobalSearchPopoverView()
}
case .posts:
if let results = searchState.postResults {
ForEach(results) { result in
SubredditPostRow(post: result, displayMode: .constant(.large))
}
}
}
}
}

struct SearchMainContentView_Previews: PreviewProvider {
Expand Down
38 changes: 28 additions & 10 deletions RedditOs/Features/Search/SearchState.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,22 @@ import Backend
class SearchState: ObservableObject {
@Published var searchText = ""
@Published var results: [SubredditSmall]?
@Published var postResults: [SubredditPost]?
@Published var filteredSubscriptions: [Subreddit]?
@Published var trending: TrendingSubreddits?
@Published var isLoading = false

private var currentUser: CurrentUserStore

private var delayedSearchCancellable: AnyCancellable?
private var instantSearchCancellable: AnyCancellable?
private var apiPublisher: AnyPublisher<SubredditResponse, Never>?
private var apiCancellable: AnyCancellable?
private var subredditSearchPublisher: AnyPublisher<SubredditResponse, Never>?
private var postSearchPublisher: AnyPublisher<ListingResponse<SubredditPost>, Never>?
private var cancellableSet: Set<AnyCancellable> = Set()
private var searchCancellableSet: Set<AnyCancellable> = Set()

init(currentUser: CurrentUserStore = .shared) {
self.currentUser = currentUser

delayedSearchCancellable = $searchText
$searchText
.subscribe(on: DispatchQueue.global())
.debounce(for: .milliseconds(500), scheduler: DispatchQueue.main)
.removeDuplicates()
Expand All @@ -42,8 +42,9 @@ class SearchState: ObservableObject {
self?.search(with: text)
}
})
.store(in: &cancellableSet)

instantSearchCancellable = $searchText
$searchText
.receive(on: DispatchQueue.main)
.sink(receiveValue: { [weak self] text in
guard let w = self else { return }
Expand All @@ -53,22 +54,39 @@ class SearchState: ObservableObject {
w.filteredSubscriptions = w.currentUser.subscriptions.filter{ $0.displayName.lowercased().contains(text.lowercased()) }
}
})
.store(in: &cancellableSet)
}

private func search(with text: String) {
apiCancellable?.cancel()
let param = ["query": text]
apiPublisher = API.shared.request(endpoint: .searchSubreddit, httpMethod: "POST", params: param)
searchCancellableSet.forEach{ $0.cancel() }

subredditSearchPublisher = API.shared.request(endpoint: .searchSubreddit, httpMethod: "POST", params: ["query": text])
.subscribe(on: DispatchQueue.global())
.replaceError(with: SubredditResponse())
.eraseToAnyPublisher()
apiCancellable = apiPublisher?

postSearchPublisher = API.shared.request(endpoint: .search, params: ["q": text])
.subscribe(on: DispatchQueue.global())
.replaceError(with: ListingResponse(error: "error"))
.eraseToAnyPublisher()

subredditSearchPublisher?
.receive(on: DispatchQueue.main)
.map{ $0.subreddits }
.sink{ [weak self] results in
self?.isLoading = false
self?.results = results
}
.store(in: &searchCancellableSet)


postSearchPublisher?
.receive(on: DispatchQueue.main)
.map{ $0.data?.children.map{ $0.data }}
.sink{ [weak self] results in
self?.postResults = results
}
.store(in: &searchCancellableSet)

}

Expand Down
11 changes: 9 additions & 2 deletions RedditOs/Features/Search/ToolbarSearchBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ struct ToolbarSearchBar: View {
@EnvironmentObject private var searchState: SearchState
@State private var isFocused = false
@State private var isPopoverPresented = false
var isPopoverEnabled: Bool

let isPopoverEnabled: Bool
let onCommit: () -> Void
let onCancel: () -> Void

var body: some View {
HStack {
Expand All @@ -21,7 +24,10 @@ struct ToolbarSearchBar: View {
if isPopoverEnabled {
isPopoverPresented = editing
}
} onCommit: {
onCommit()
}

.keyboardShortcut("f", modifiers: .command)
.padding(8)
.background(RoundedRectangle(cornerRadius: 8)
Expand All @@ -39,6 +45,7 @@ struct ToolbarSearchBar: View {
if !searchState.searchText.isEmpty {
Button {
searchState.searchText = ""
onCancel()
} label: {
Image(systemName: "xmark.circle")
.font(.title2)
Expand All @@ -53,6 +60,6 @@ struct ToolbarSearchBar: View {

struct ToolbarSearchBar_Previews: PreviewProvider {
static var previews: some View {
ToolbarSearchBar(isPopoverEnabled: true).environmentObject(SearchState())
ToolbarSearchBar(isPopoverEnabled: true, onCommit: { }, onCancel: { }).environmentObject(SearchState())
}
}

0 comments on commit 9378834

Please sign in to comment.