#1731 Add option to add feed by url

This commit is contained in:
Andrei 2022-09-20 20:45:16 -07:00
parent 8fd423182e
commit a953d74a45
4 changed files with 42 additions and 27 deletions

View file

@ -20,7 +20,6 @@ import com.newsblur.util.executeAsyncTask
import dagger.hilt.android.AndroidEntryPoint
import java.net.MalformedURLException
import java.net.URL
import java.util.*
import javax.inject.Inject
@AndroidEntryPoint
@ -86,13 +85,9 @@ class FeedSearchActivity : NbActivity(), OnFeedSearchResultClickListener, AddFee
override fun afterTextChanged(s: Editable) {
searchQueryRunnable?.let { handler.removeCallbacks(it) }
searchQueryRunnable = Runnable {
if (tryAddByURL(s.toString())) {
return@Runnable
}
syncClearIconVisibility(s)
if (s.isNotEmpty()) searchQuery(s)
else syncSearchResults(arrayOf())
else syncSearchResults(emptyList())
}
handler.postDelayed(searchQueryRunnable!!, 350)
}
@ -111,7 +106,12 @@ class FeedSearchActivity : NbActivity(), OnFeedSearchResultClickListener, AddFee
onPostExecute = {
binding.loadingCircle.visibility = View.GONE
binding.clearText.visibility = View.VISIBLE
syncSearchResults(it ?: arrayOf())
syncSearchResults(buildList {
if (matchesUrl(query.toString())) {
add(FeedResult.createFeedResultForUrl(query.toString().lowercase()))
}
addAll(it ?: arrayOf())
})
}
)
}
@ -120,15 +120,20 @@ class FeedSearchActivity : NbActivity(), OnFeedSearchResultClickListener, AddFee
binding.clearText.visibility = if (query.isNotEmpty()) View.VISIBLE else View.GONE
}
private fun syncSearchResults(results: Array<FeedResult>) {
private fun syncSearchResults(results: List<FeedResult>) {
adapter.replaceAll(results)
}
private fun showAddFeedDialog(feedUrl: String, feedLabel: String) {
val addFeedFragment: DialogFragment = AddFeedFragment.newInstance(feedUrl, feedLabel)
addFeedFragment.show(supportFragmentManager, "dialog")
}
/**
* See if the text entered in the query field was actually a URL so we can skip the
* search step and just let users who know feed URLs directly subscribe.
* See if the text entered in the query field was actually a URL
* to let users who know feed URLs directly subscribe.
*/
private fun tryAddByURL(s: String): Boolean {
private fun matchesUrl(s: String): Boolean {
var u: URL? = null
try {
u = URL(s)
@ -144,12 +149,6 @@ class FeedSearchActivity : NbActivity(), OnFeedSearchResultClickListener, AddFee
if (u.host == null || u.host.trim().isEmpty()) {
return false
}
showAddFeedDialog(s, s)
return true
}
private fun showAddFeedDialog(feedUrl: String, feedLabel: String) {
val addFeedFragment: DialogFragment = AddFeedFragment.newInstance(feedUrl, feedLabel)
addFeedFragment.show(supportFragmentManager, "dialog")
}
}

View file

@ -8,8 +8,9 @@ import androidx.recyclerview.widget.RecyclerView
import com.newsblur.R
import com.newsblur.databinding.ViewFeedSearchRowBinding
import com.newsblur.domain.FeedResult
import com.newsblur.util.FeedUtils
import com.newsblur.util.ImageLoader
import com.newsblur.util.setViewGone
import com.newsblur.util.setViewVisible
class FeedSearchAdapter(
private val onClickListener: OnFeedSearchResultClickListener,
@ -30,12 +31,11 @@ class FeedSearchAdapter(
override fun getItemCount(): Int = resultsList.size
fun replaceAll(results: Array<FeedResult>) {
val newResultsList: List<FeedResult> = results.toList()
val diffCallback = ResultDiffCallback(resultsList, newResultsList)
fun replaceAll(results: List<FeedResult>) {
val diffCallback = ResultDiffCallback(resultsList, results)
val diffResult = DiffUtil.calculateDiff(diffCallback)
resultsList.clear()
resultsList.addAll(newResultsList)
resultsList.addAll(results)
diffResult.dispatchUpdatesTo(this)
}
@ -46,19 +46,25 @@ class FeedSearchAdapter(
fun bind(result: FeedResult) {
val resultFaviconUrl = result.faviconUrl
if (resultFaviconUrl.isNotEmpty()) {
iconLoader.displayImage(resultFaviconUrl, binding.imgFeedIcon)
iconLoader.displayImage(resultFaviconUrl, binding.imgFeedIcon)
}
binding.textTitle.text = result.label
binding.textTagline.text = result.tagline
val subscribersCountText = binding.root.context.getString(R.string.feed_subscribers, result.numberOfSubscriber)
binding.textSubscriptionCount.text = subscribersCountText
if (result.numberOfSubscriber > 0) {
val subscribersCountText = binding.root.context.getString(R.string.feed_subscribers, result.numberOfSubscriber)
binding.textSubscriptionCount.text = subscribersCountText
binding.textSubscriptionCount.setViewVisible()
} else {
binding.textSubscriptionCount.setViewGone()
}
if (result.url.isNotEmpty()) {
binding.rowResultAddress.text = result.url
binding.rowResultAddress.visibility = View.VISIBLE
binding.rowResultAddress.setViewVisible()
} else {
binding.rowResultAddress.visibility = View.GONE
binding.rowResultAddress.setViewGone()
}
itemView.setOnClickListener {

View file

@ -18,4 +18,13 @@ data class FeedResult(
val faviconUrl: String
get() = "${APIConstants.buildUrl(APIConstants.PATH_FEED_FAVICON_URL)}$id"
companion object {
fun createFeedResultForUrl(url: String) = FeedResult(
id = -1,
tagline = "Add feed manually by URL",
label = url,
url = url
)
}
}

View file

@ -570,6 +570,7 @@ public class APIManager {
return response.getResponse(gson, AddFeedResponse.class);
}
@Nullable
public FeedResult[] searchForFeed(String searchTerm) {
ContentValues values = new ContentValues();
values.put(APIConstants.PARAMETER_FEED_SEARCH_TERM, searchTerm);