Skip to content

Commit

Permalink
Merge pull request #1588 from planetary-social/search-relays-autocomp…
Browse files Browse the repository at this point in the history
…lete

Search relays during mentions autocomplete
pelumy authored Oct 11, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents ae758bc + a2f58f4 commit 58002ca
Showing 5 changed files with 45 additions and 51 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Removed image and video link text from notes. Now only the images and videos will appear, without the link. [#1487](https://github.com/planetary-social/nos/issues/1487)
- Added a broken link icon that appears when an image fails to load. [#1583](https://github.com/planetary-social/nos/issues/1583)
- Added new translations for the app so you can use it in Korean, Chinese Simplified, Swedish, and more! Thanks to alternative, 안마리 (everyscreennetwork), Andypsl8, Dženan (Dzenan), ObjectifMoon, ra5pvt1n, and everyone else who contributed translations on Crowdin!
- Updated user mentions search functionality to also search relays in the user's relay list. [#1560](https://github.com/planetary-social/nos/issues/1560)
- Added Build Your Network screen to onboarding to explain how the feed works. [#1600](https://github.com/planetary-social/nos/issues/1600)
- Decreased the opacity on disabled buttons.
- Added a Delete Account button to the Settings screen. [#80](https://github.com/planetary-social/nos/issues/80)
30 changes: 27 additions & 3 deletions Nos/Controller/SearchController.swift
Original file line number Diff line number Diff line change
@@ -22,6 +22,15 @@ enum SearchState {
case stillLoading
}

/// Represents the origin from which a search is initiated.
enum SearchOrigin {
/// Search initiated from the Discover tab
case discover

/// Search initiated from the mentions `AuthorListView`
case mentions
}

/// Manages a search query and list of results.
class SearchController: ObservableObject {

@@ -54,9 +63,14 @@ class SearchController: ObservableObject {
/// The amount of time, in seconds, to remain in the `.loading` state until switching to `.stillLoading`.
private let stillLoadingTime: TimeInterval = 10

/// The origin of the current search.
let searchOrigin: SearchOrigin

// MARK: - Init

init() {
init(searchOrigin: SearchOrigin = .discover) {
self.searchOrigin = searchOrigin

$query
.removeDuplicates()
.map { [weak self] query in
@@ -70,7 +84,12 @@ class SearchController: ObservableObject {
guard let self else { return nil }
if self.state == .noQuery {
// User is starting a new search
analytics.searchedDiscover()
switch searchOrigin {
case .discover:
analytics.searchedDiscover()
case .mentions:
analytics.searchedMentions()
}
}
self.authorResults = self.authors(named: query)
if self.authorResults.isEmpty {
@@ -90,6 +109,11 @@ class SearchController: ObservableObject {
}
.store(in: &cancellables)

observeContextChanges()
}

/// Observes changes in the `NSManagedObjectContext` and updates the query and author results.
func observeContextChanges() {
NotificationCenter.default.publisher(
for: NSNotification.Name.NSManagedObjectContextObjectsDidChange,
object: context
@@ -107,7 +131,7 @@ class SearchController: ObservableObject {
})
.store(in: &cancellables)
}

// MARK: - Internal

func author(fromPublicKey publicKeyString: String) -> Author? {
5 changes: 5 additions & 0 deletions Nos/Service/Analytics.swift
Original file line number Diff line number Diff line change
@@ -160,6 +160,11 @@ class Analytics {
track("Discover Search Started")
}

/// Tracks when the user submits a search on the Mentions screen.
func searchedMentions() {
track("Mentions Search Started")
}

/// Tracks when the user taps on a search result on the Discover screen.
func displayedAuthorFromDiscoverSearch(resultsCount: Int) {
track(
59 changes: 11 additions & 48 deletions Nos/Views/Components/Author/AuthorListView.swift
Original file line number Diff line number Diff line change
@@ -7,48 +7,37 @@ struct AuthorListView: View {

@Environment(\.managedObjectContext) private var viewContext

@State private var authors: [Author]?
@StateObject private var searchController = SearchController(searchOrigin: .mentions)

@State private var filteredAuthors: [Author]?

@StateObject private var searchTextObserver = SearchTextFieldObserver()

@FocusState private var isSearching: Bool

var didSelectGesture: ((Author) -> Void)?

var body: some View {
ScrollView(.vertical) {
SearchBar(text: $searchTextObserver.text, isSearching: $isSearching)
SearchBar(text: $searchController.query, isSearching: $isSearching)
.readabilityPadding()
.padding(.top, 10)
.onSubmit {
searchController.submitSearch(query: searchController.query)
}
LazyVStack {
if let authors = filteredAuthors {
ForEach(authors) { author in
AuthorCard(author: author, showsFollowButton: false) {
didSelectGesture?(author)
}
.padding(.horizontal, 13)
.padding(.top, 5)
.readabilityPadding()
ForEach(searchController.authorResults) { author in
AuthorCard(author: author, showsFollowButton: false) {
didSelectGesture?(author)
}
} else {
ProgressView()
.padding(.horizontal, 13)
.padding(.top, 5)
.readabilityPadding()
}
}
}
.background(Color.appBg)
.nosNavigationBar(title: .localizable.mention)
.onChange(of: searchTextObserver.debouncedText) { _, newValue in
search(for: newValue)
}
.onAppear {
isSearching = true
}
.disableAutocorrection(true)
.task {
refreshAuthors()
}
.toolbar {
ToolbarItem(placement: .cancellationAction) {
Button(action: {
@@ -60,30 +49,4 @@ struct AuthorListView: View {
}
}
}

private func refreshAuthors() {
let request = Author.allAuthorsWithNameOrDisplayNameRequest(muted: false)
authors = try? viewContext.fetch(request)
search(for: searchTextObserver.text)
}

private func search(for query: String) {
guard !query.isEmpty else {
filteredAuthors = authors
return
}
let lowercasedQuery = query.lowercased()
filteredAuthors = authors?.filter { author in
if author.name?.lowercased().contains(lowercasedQuery) == true {
return true
}
if author.displayName?.lowercased().contains(lowercasedQuery) == true {
return true
}
if author.hexadecimalPublicKey?.lowercased().contains(lowercasedQuery) == true {
return true
}
return false
}
}
}
1 change: 1 addition & 0 deletions Nos/Views/Components/SearchBar.swift
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@ struct SearchBar: View {
isSearching.wrappedValue = true // Set focus to the search bar when tapped
}
.focused(isSearching)
.submitLabel(.search)
Spacer()
}
.padding(8)

0 comments on commit 58002ca

Please sign in to comment.