mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
#1573 Feed search favicon loading.
This commit is contained in:
parent
5b50fe402a
commit
7329f54d62
8 changed files with 119 additions and 120 deletions
|
@ -136,7 +136,7 @@
|
|||
android:label="@string/mute_sites"/>
|
||||
|
||||
<activity
|
||||
android:name=".activity.SearchForFeeds"
|
||||
android:name=".activity.FeedSearchActivity"
|
||||
android:launchMode="singleTop" />
|
||||
|
||||
<activity
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.net.MalformedURLException
|
|||
import java.net.URL
|
||||
import java.util.*
|
||||
|
||||
class SearchForFeeds : NbActivity(), OnFeedSearchResultClickListener, AddFeedProgressListener {
|
||||
class FeedSearchActivity : NbActivity(), OnFeedSearchResultClickListener, AddFeedProgressListener {
|
||||
|
||||
private val supportedUrlProtocols: MutableSet<String> = HashSet(2)
|
||||
|
||||
|
@ -40,7 +40,6 @@ class SearchForFeeds : NbActivity(), OnFeedSearchResultClickListener, AddFeedPro
|
|||
setupListeners()
|
||||
apiManager = APIManager(this)
|
||||
binding.inputSearchQuery.requestFocus()
|
||||
lifecycleScope
|
||||
}
|
||||
|
||||
override fun onFeedSearchResultClickListener(result: FeedResult) {
|
|
@ -0,0 +1,94 @@
|
|||
package com.newsblur.activity
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.newsblur.R
|
||||
import com.newsblur.databinding.ViewFeedSearchRowBinding
|
||||
import com.newsblur.domain.FeedResult
|
||||
import com.newsblur.util.FeedUtils
|
||||
|
||||
class FeedSearchAdapter(
|
||||
private val onClickListener: OnFeedSearchResultClickListener
|
||||
) : RecyclerView.Adapter<FeedSearchAdapter.ViewHolder>() {
|
||||
|
||||
private val resultsList: MutableList<FeedResult> = mutableListOf()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.view_feed_search_row, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val result = resultsList[position]
|
||||
holder.bind(result)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = resultsList.size
|
||||
|
||||
fun replaceAll(results: Array<FeedResult>) {
|
||||
val newResultsList: List<FeedResult> = results.toList()
|
||||
val diffCallback = ResultDiffCallback(resultsList, newResultsList)
|
||||
val diffResult = DiffUtil.calculateDiff(diffCallback)
|
||||
resultsList.clear()
|
||||
resultsList.addAll(newResultsList)
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
private val binding: ViewFeedSearchRowBinding = ViewFeedSearchRowBinding.bind(itemView)
|
||||
|
||||
fun bind(result: FeedResult) {
|
||||
val resultFaviconUrl = result.faviconUrl
|
||||
if (resultFaviconUrl.isNotEmpty()) {
|
||||
FeedUtils.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.url.isNotEmpty()) {
|
||||
binding.rowResultAddress.text = result.url
|
||||
binding.rowResultAddress.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.rowResultAddress.visibility = View.GONE
|
||||
}
|
||||
|
||||
itemView.setOnClickListener {
|
||||
onClickListener.onFeedSearchResultClickListener(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class ResultDiffCallback(
|
||||
private val oldList: List<FeedResult>,
|
||||
private val newList: List<FeedResult>) : DiffUtil.Callback() {
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldFeedResult = oldList[oldItemPosition]
|
||||
val newFeedResult = newList[newItemPosition]
|
||||
return oldFeedResult == newFeedResult
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldFeedResult = oldList[oldItemPosition]
|
||||
val newFeedResult = newList[newItemPosition]
|
||||
return oldFeedResult.id == newFeedResult.id
|
||||
&& oldFeedResult.label == newFeedResult.label
|
||||
}
|
||||
|
||||
override fun getOldListSize(): Int = oldList.size
|
||||
|
||||
override fun getNewListSize(): Int = newList.size
|
||||
}
|
||||
|
||||
interface OnFeedSearchResultClickListener {
|
||||
|
||||
fun onFeedSearchResultClickListener(result: FeedResult)
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
package com.newsblur.activity
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.text.TextUtils
|
||||
import android.util.Base64
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.newsblur.R
|
||||
import com.newsblur.databinding.ViewFeedSearchRowBinding
|
||||
import com.newsblur.domain.FeedResult
|
||||
|
||||
internal class FeedSearchAdapter(private val onClickListener: OnFeedSearchResultClickListener) : RecyclerView.Adapter<FeedSearchAdapter.ViewHolder>() {
|
||||
|
||||
private val resultsList: MutableList<FeedResult> = ArrayList()
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.view_feed_search_row, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val result = resultsList[position]
|
||||
var bitmap: Bitmap? = null
|
||||
if (!TextUtils.isEmpty(result.favicon)) {
|
||||
val data = Base64.decode(result.favicon, Base64.DEFAULT)
|
||||
bitmap = BitmapFactory.decodeByteArray(data, 0, data.size)
|
||||
}
|
||||
bitmap?.let {
|
||||
holder.binding.imgFeedIcon.setImageBitmap(bitmap)
|
||||
}
|
||||
|
||||
holder.binding.textTitle.text = result.label
|
||||
holder.binding.textTagline.text = result.tagline
|
||||
val subscribersCountText = holder.binding.root.context.resources.getString(R.string.feed_subscribers, result.numberOfSubscriber)
|
||||
holder.binding.textSubscriptionCount.text = subscribersCountText
|
||||
|
||||
if (!TextUtils.isEmpty(result.url)) {
|
||||
holder.binding.rowResultAddress.text = result.url
|
||||
holder.binding.rowResultAddress.visibility = View.VISIBLE
|
||||
} else {
|
||||
holder.binding.rowResultAddress.visibility = View.GONE
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener {
|
||||
onClickListener.onFeedSearchResultClickListener(result)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = resultsList.size
|
||||
|
||||
fun replaceAll(results: Array<FeedResult>) {
|
||||
val newResultsList: List<FeedResult> = results.toList()
|
||||
val diffCallback = ResultDiffCallback(resultsList, newResultsList)
|
||||
val diffResult = DiffUtil.calculateDiff(diffCallback)
|
||||
resultsList.clear()
|
||||
resultsList.addAll(newResultsList)
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
internal class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val binding: ViewFeedSearchRowBinding = ViewFeedSearchRowBinding.bind(itemView)
|
||||
}
|
||||
|
||||
internal class ResultDiffCallback(private val oldList: List<FeedResult>,
|
||||
private val newList: List<FeedResult>) : DiffUtil.Callback() {
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldFeedResult = oldList[oldItemPosition]
|
||||
val newFeedResult = newList[newItemPosition]
|
||||
return oldFeedResult.label == newFeedResult.label &&
|
||||
oldFeedResult.numberOfSubscriber == newFeedResult.numberOfSubscriber
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldFeedResult = oldList[oldItemPosition]
|
||||
val newFeedResult = newList[newItemPosition]
|
||||
return oldFeedResult.label == newFeedResult.label
|
||||
&& oldFeedResult.tagline == newFeedResult.tagline
|
||||
}
|
||||
|
||||
override fun getOldListSize(): Int = oldList.size
|
||||
|
||||
override fun getNewListSize(): Int = newList.size
|
||||
}
|
||||
|
||||
interface OnFeedSearchResultClickListener {
|
||||
|
||||
fun onFeedSearchResultClickListener(result: FeedResult)
|
||||
}
|
||||
}
|
|
@ -340,7 +340,7 @@ public class Main extends NbActivity implements StateChangedListener, SwipeRefre
|
|||
}
|
||||
|
||||
private void onClickAddButton() {
|
||||
Intent i = new Intent(this, SearchForFeeds.class);
|
||||
Intent i = new Intent(this, FeedSearchActivity.class);
|
||||
startActivity(i);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package com.newsblur.domain;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class FeedResult {
|
||||
|
||||
@SerializedName("num_subscribers")
|
||||
public int numberOfSubscriber;
|
||||
|
||||
@SerializedName("favicon_color")
|
||||
public String faviconColor;
|
||||
|
||||
@SerializedName("value")
|
||||
public String url;
|
||||
|
||||
public String tagline;
|
||||
|
||||
public String label;
|
||||
|
||||
public String favicon;
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.newsblur.domain
|
||||
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.newsblur.network.APIConstants
|
||||
|
||||
data class FeedResult(
|
||||
@SerializedName("id")
|
||||
val id: Int = 0,
|
||||
@SerializedName("tagline")
|
||||
val tagline: String? = null,
|
||||
@SerializedName("label")
|
||||
val label: String,
|
||||
@SerializedName("num_subscribers")
|
||||
val numberOfSubscriber: Int = 0,
|
||||
@SerializedName("value")
|
||||
val url: String,
|
||||
) {
|
||||
|
||||
val faviconUrl: String
|
||||
get() = "${APIConstants.buildUrl(APIConstants.PATH_FEED_FAVICON_URL)}$id"
|
||||
}
|
|
@ -81,6 +81,7 @@ public class APIConstants {
|
|||
public static final String PATH_RENAME_FOLDER = "/reader/rename_folder";
|
||||
public static final String PATH_SAVE_RECEIPT = "/profile/save_android_receipt";
|
||||
public static final String PATH_FEED_STATISTICS = "/rss_feeds/statistics_embedded/";
|
||||
public static final String PATH_FEED_FAVICON_URL = "/rss_feeds/icon/";
|
||||
|
||||
public static String buildUrl(String path) {
|
||||
return CurrentUrlBase + path;
|
||||
|
|
Loading…
Add table
Reference in a new issue