Skip to content
This repository was archived by the owner on Feb 17, 2020. It is now read-only.

Commit 9bbe9b1

Browse files
authored
Merge pull request #520 from squanchy-dev/move_search_logic_to_service
Move search logic to service
2 parents 7cafd99 + 0c994bc commit 9bbe9b1

14 files changed

Lines changed: 182 additions & 841 deletions

app/src/main/java/net/squanchy/search/SearchActivity.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ class SearchActivity : AppCompatActivity(), SearchRecyclerView.OnSearchResultCli
7474

7575
val searchSubscription = querySubject.throttleLast(QUERY_DEBOUNCE_TIMEOUT, TimeUnit.MILLISECONDS)
7676
.doOnNext(::updateSearchActionIcon)
77-
.startWith(EMPTY_QUERY)
77+
.startWith(getInitialQuery())
7878
.flatMap(searchService::find)
7979
.distinctUntilChanged()
8080
.subscribeOn(Schedulers.io())
@@ -93,6 +93,11 @@ class SearchActivity : AppCompatActivity(), SearchRecyclerView.OnSearchResultCli
9393
searchField.requestFocus()
9494
}
9595

96+
private fun getInitialQuery(): String {
97+
val text = searchField.text
98+
return text?.toString() ?: EMPTY_QUERY
99+
}
100+
96101
private fun updateSearchActionIcon(query: String) {
97102
hasQuery = query.isNotEmpty()
98103
invalidateOptionsMenu()

app/src/main/java/net/squanchy/search/SearchResult.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,25 @@ import net.squanchy.speaker.domain.view.Speaker
55

66
sealed class SearchResult {
77

8-
data class Success(val events: List<Event>, val speakers: List<Speaker>) : SearchResult() {
8+
data class Success(val elements: List<SearchListElement>) : SearchResult() {
99
val isEmpty: Boolean
10-
get() = events.isEmpty() && speakers.isEmpty()
10+
get() = elements.isEmpty()
1111
}
1212

1313
object Error : SearchResult()
1414

1515
companion object {
1616

17-
private val emptySearch = SearchResult.Success(emptyList(), emptyList())
17+
private val emptySearch = SearchResult.Success(emptyList())
1818

1919
fun empty(): SearchResult = emptySearch
2020
}
2121
}
22+
23+
sealed class SearchListElement {
24+
object EventHeader : SearchListElement()
25+
data class EventElement(val event: Event) : SearchListElement()
26+
object SpeakerHeader : SearchListElement()
27+
data class SpeakerElement(val speaker: Speaker) : SearchListElement()
28+
object AlgoliaLogo : SearchListElement()
29+
}

app/src/main/java/net/squanchy/search/SearchService.kt

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ import net.squanchy.search.algolia.model.AlgoliaSearchResult
88
import net.squanchy.search.algolia.model.AlgoliaSearchResult.QueryNotLongEnough
99
import net.squanchy.search.algolia.model.AlgoliaSearchResult.ErrorSearching
1010
import net.squanchy.search.algolia.model.AlgoliaSearchResult.Matches
11+
import net.squanchy.search.SearchListElement.SpeakerHeader
12+
import net.squanchy.search.SearchListElement.EventHeader
13+
import net.squanchy.search.SearchListElement.SpeakerElement
14+
import net.squanchy.search.SearchListElement.AlgoliaLogo
15+
import net.squanchy.search.SearchListElement.EventElement
1116
import net.squanchy.service.repository.AuthService
1217
import net.squanchy.service.repository.EventRepository
1318
import net.squanchy.service.repository.SpeakerRepository
@@ -34,16 +39,41 @@ class SearchService(
3439
private fun combineWithSearchResult(): Function3<List<Event>, List<Speaker>, AlgoliaSearchResult, SearchResult> {
3540
return Function3 { events, speakers, result ->
3641
when (result) {
37-
is QueryNotLongEnough -> SearchResult.Success(emptyList(), speakers)
42+
is QueryNotLongEnough -> SearchResult.Success(createResultForQueryNotLongEnough(speakers))
3843
is ErrorSearching -> SearchResult.Error
39-
is Matches -> SearchResult.Success(
40-
events.filter { result.eventIds.contains(it.id) },
41-
speakers.filter { result.speakerIds.contains(it.id) }
42-
)
44+
is Matches -> {
45+
val filteredEvents = events.filter { result.eventIds.contains(it.id) }
46+
val filteredSpeakers = speakers.filter { result.speakerIds.contains(it.id) }
47+
SearchResult.Success(createResultForSuccessfulSearch(filteredEvents, filteredSpeakers))
48+
}
4349
}
4450
}
4551
}
4652

53+
private fun createResultForQueryNotLongEnough(speakers: List<Speaker>): List<SearchListElement> {
54+
return listOf(SpeakerHeader) + speakers.map(::SpeakerElement)
55+
}
56+
57+
private fun createResultForSuccessfulSearch(events: List<Event>, speakers: List<Speaker>): List<SearchListElement> {
58+
if (speakers.isEmpty() && events.isEmpty()) {
59+
return emptyList()
60+
}
61+
62+
return ArrayList<SearchListElement>(events.size + speakers.size).apply {
63+
if (events.isNotEmpty()) {
64+
add(EventHeader)
65+
addAll(events.map(::EventElement))
66+
}
67+
68+
if (speakers.isNotEmpty()) {
69+
add(SpeakerHeader)
70+
addAll(speakers.map(::SpeakerElement))
71+
}
72+
73+
add(AlgoliaLogo)
74+
}
75+
}
76+
4777
fun speakers(): Observable<List<Speaker>> {
4878
return speakerRepository.speakers()
4979
.map { it.sortedBy(Speaker::name) }

app/src/main/java/net/squanchy/search/view/AlgoliaLogoViewHolder.kt

Lines changed: 0 additions & 6 deletions
This file was deleted.

app/src/main/java/net/squanchy/search/view/GridSpanSizeLookup.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
package net.squanchy.search.view
22

33
import android.support.v7.widget.GridLayoutManager
4-
import net.squanchy.search.view.SearchAdapter.Companion.ViewTypeId
4+
import net.squanchy.search.SearchListElement
55

6-
internal class GridSpanSizeLookup(private val itemsAdapter: ItemsAdapter, private val columnCount: Int) : GridLayoutManager.SpanSizeLookup() {
6+
internal class GridSpanSizeLookup(private val items: List<SearchListElement>, private val columnCount: Int) : GridLayoutManager.SpanSizeLookup() {
77

88
init {
99
super.setSpanIndexCacheEnabled(true)
1010
}
1111

1212
override fun getSpanSize(position: Int): Int {
13-
return if (itemsAdapter.isEmpty) SINGLE_COLUMN_SPAN_SIZE else getSpanSizeFor(itemsAdapter.viewTypeAtAbsolutePosition(position))
13+
return if (items.isEmpty()) SINGLE_COLUMN_SPAN_SIZE else getSpanSizeFor(items[position])
1414
}
1515

16-
private fun getSpanSizeFor(@ViewTypeId viewTypeId: Int): Int =
17-
when (viewTypeId) {
18-
SearchAdapter.HEADER -> columnCount
19-
SearchAdapter.EVENT -> columnCount
20-
SearchAdapter.SPEAKER -> SINGLE_COLUMN_SPAN_SIZE
21-
SearchAdapter.ALGOLIA_LOGO -> columnCount
22-
else -> error("Invalid ViewTypeId $viewTypeId")
16+
private fun getSpanSizeFor(element: SearchListElement): Int =
17+
when (element) {
18+
is SearchListElement.EventHeader -> columnCount
19+
is SearchListElement.SpeakerHeader -> columnCount
20+
is SearchListElement.EventElement -> columnCount
21+
is SearchListElement.SpeakerElement -> SINGLE_COLUMN_SPAN_SIZE
22+
is SearchListElement.AlgoliaLogo -> columnCount
2323
}
2424

2525
companion object {

app/src/main/java/net/squanchy/search/view/HeaderViewHolder.kt

Lines changed: 0 additions & 16 deletions
This file was deleted.

app/src/main/java/net/squanchy/search/view/ItemsAdapter.kt

Lines changed: 0 additions & 135 deletions
This file was deleted.

0 commit comments

Comments
 (0)