forked from mozilla-mobile/firefox-android
-
Notifications
You must be signed in to change notification settings - Fork 0
/
FxSuggestSuggestionProvider.kt
103 lines (95 loc) · 3.96 KB
/
FxSuggestSuggestionProvider.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package mozilla.components.feature.fxsuggest
import android.content.res.Resources
import mozilla.appservices.suggest.Suggestion
import mozilla.appservices.suggest.SuggestionProvider
import mozilla.appservices.suggest.SuggestionQuery
import mozilla.components.concept.awesomebar.AwesomeBar
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.support.ktx.kotlin.toBitmap
import java.util.UUID
/**
* An [AwesomeBar.SuggestionProvider] that returns Firefox Suggest search suggestions.
*
* @param resources Your application's [Resources] instance.
* @param loadUrlUseCase A use case that loads a suggestion's URL when clicked.
* @param includeSponsoredSuggestions Whether to return suggestions for sponsored content.
* @param includeNonSponsoredSuggestions Whether to return suggestions for web content.
* @param suggestionsHeader An optional header title for grouping the returned suggestions.
*/
class FxSuggestSuggestionProvider(
private val resources: Resources,
private val loadUrlUseCase: SessionUseCases.LoadUrlUseCase,
private val includeSponsoredSuggestions: Boolean,
private val includeNonSponsoredSuggestions: Boolean,
private val suggestionsHeader: String? = null,
) : AwesomeBar.SuggestionProvider {
override val id: String = UUID.randomUUID().toString()
override fun groupTitle(): String? = suggestionsHeader
override suspend fun onInputChanged(text: String): List<AwesomeBar.Suggestion> =
if (text.isEmpty()) {
emptyList()
} else {
val providers = buildList() {
if (includeSponsoredSuggestions) {
add(SuggestionProvider.AMP)
}
if (includeNonSponsoredSuggestions) {
add(SuggestionProvider.WIKIPEDIA)
}
}
GlobalFxSuggestDependencyProvider.requireStorage().query(
SuggestionQuery(
keyword = text,
providers = providers,
),
).into()
}
override fun onInputCancelled() {
GlobalFxSuggestDependencyProvider.requireStorage().cancelReads()
}
private suspend fun List<Suggestion>.into(): List<AwesomeBar.Suggestion> =
mapNotNull { suggestion ->
val details = when (suggestion) {
is Suggestion.Amp -> SuggestionDetails(
title = suggestion.title,
url = suggestion.url,
fullKeyword = suggestion.fullKeyword,
isSponsored = true,
icon = suggestion.icon,
)
is Suggestion.Wikipedia -> SuggestionDetails(
title = suggestion.title,
url = suggestion.url,
fullKeyword = suggestion.fullKeyword,
isSponsored = false,
icon = suggestion.icon,
)
else -> return@mapNotNull null
}
AwesomeBar.Suggestion(
provider = this@FxSuggestSuggestionProvider,
icon = details.icon?.let {
it.toUByteArray().asByteArray().toBitmap()
},
title = "${details.fullKeyword} — ${details.title}",
description = if (details.isSponsored) {
resources.getString(R.string.sponsored_suggestion_description)
} else {
null
},
onSuggestionClicked = {
loadUrlUseCase.invoke(details.url)
},
)
}
}
internal data class SuggestionDetails(
val title: String,
val url: String,
val fullKeyword: String,
val isSponsored: Boolean,
val icon: List<UByte>?,
)