Big code cleaning.
This commit is contained in:
parent
216c639a23
commit
437aa0abec
@ -27,8 +27,6 @@ import bou.amine.apps.readerforselfossv2.android.adapters.ItemListAdapter
|
|||||||
import bou.amine.apps.readerforselfossv2.android.adapters.ItemsAdapter
|
import bou.amine.apps.readerforselfossv2.android.adapters.ItemsAdapter
|
||||||
import bou.amine.apps.readerforselfossv2.android.background.LoadingWorker
|
import bou.amine.apps.readerforselfossv2.android.background.LoadingWorker
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.ActivityHomeBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.ActivityHomeBinding
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.getIcon
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.getTitleDecoded
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
|
import bou.amine.apps.readerforselfossv2.android.settings.SettingsActivity
|
||||||
import bou.amine.apps.readerforselfossv2.android.themes.AppColors
|
import bou.amine.apps.readerforselfossv2.android.themes.AppColors
|
||||||
import bou.amine.apps.readerforselfossv2.android.themes.Toppings
|
import bou.amine.apps.readerforselfossv2.android.themes.Toppings
|
||||||
@ -39,10 +37,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActiv
|
|||||||
import bou.amine.apps.readerforselfossv2.dao.ACTION
|
import bou.amine.apps.readerforselfossv2.dao.ACTION
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.utils.ItemType
|
import bou.amine.apps.readerforselfossv2.utils.*
|
||||||
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
|
||||||
import bou.amine.apps.readerforselfossv2.utils.longHash
|
|
||||||
import bou.amine.apps.readerforselfossv2.utils.toView
|
|
||||||
import com.ashokvarma.bottomnavigation.BottomNavigationBar
|
import com.ashokvarma.bottomnavigation.BottomNavigationBar
|
||||||
import com.ashokvarma.bottomnavigation.BottomNavigationItem
|
import com.ashokvarma.bottomnavigation.BottomNavigationItem
|
||||||
import com.ashokvarma.bottomnavigation.TextBadgeItem
|
import com.ashokvarma.bottomnavigation.TextBadgeItem
|
||||||
@ -550,7 +545,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
|||||||
} else {
|
} else {
|
||||||
for (source in maybeSources) {
|
for (source in maybeSources) {
|
||||||
val item = PrimaryDrawerItem().apply {
|
val item = PrimaryDrawerItem().apply {
|
||||||
nameText = source.getTitleDecoded()
|
nameText = source.title.getHtmlDecoded()
|
||||||
identifier = source.id.toLong()
|
identifier = source.id.toLong()
|
||||||
iconUrl = source.getIcon(repository.baseUrl)
|
iconUrl = source.getIcon(repository.baseUrl)
|
||||||
onDrawerItemClickListener = { _,_,_ ->
|
onDrawerItemClickListener = { _,_,_ ->
|
||||||
|
@ -14,7 +14,6 @@ import bou.amine.apps.readerforselfossv2.android.databinding.ActivityReaderBindi
|
|||||||
import bou.amine.apps.readerforselfossv2.android.fragments.ArticleFragment
|
import bou.amine.apps.readerforselfossv2.android.fragments.ArticleFragment
|
||||||
import bou.amine.apps.readerforselfossv2.android.themes.AppColors
|
import bou.amine.apps.readerforselfossv2.android.themes.AppColors
|
||||||
import bou.amine.apps.readerforselfossv2.android.themes.Toppings
|
import bou.amine.apps.readerforselfossv2.android.themes.Toppings
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.toggleStar
|
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
|
@ -17,6 +17,9 @@ import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop
|
|||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getIcon
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getThumbnail
|
||||||
import com.amulyakhare.textdrawable.TextDrawable
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
import com.amulyakhare.textdrawable.util.ColorGenerator
|
import com.amulyakhare.textdrawable.util.ColorGenerator
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
@ -56,7 +59,7 @@ class ItemCardAdapter(
|
|||||||
val itm = items[position]
|
val itm = items[position]
|
||||||
|
|
||||||
binding.favButton.isSelected = itm.starred
|
binding.favButton.isSelected = itm.starred
|
||||||
binding.title.text = itm.getTitleDecoded()
|
binding.title.text = itm.title.getHtmlDecoded()
|
||||||
|
|
||||||
binding.title.setOnTouchListener(LinkOnTouchListener())
|
binding.title.setOnTouchListener(LinkOnTouchListener())
|
||||||
|
|
||||||
@ -79,13 +82,13 @@ class ItemCardAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (itm.getIcon(repository.baseUrl).isEmpty()) {
|
if (itm.getIcon(repository.baseUrl).isEmpty()) {
|
||||||
val color = generator.getColor(itm.getSourceTitle())
|
val color = generator.getColor(itm.title.getHtmlDecoded())
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.getSourceTitle().toTextDrawableString(c), color)
|
.build(itm.title.getHtmlDecoded().toTextDrawableString(), color)
|
||||||
binding.sourceImage.setImageDrawable(drawable)
|
binding.sourceImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
c.circularBitmapDrawable(config, itm.getIcon(repository.baseUrl), binding.sourceImage)
|
c.circularBitmapDrawable(config, itm.getIcon(repository.baseUrl), binding.sourceImage)
|
||||||
@ -126,7 +129,7 @@ class ItemCardAdapter(
|
|||||||
|
|
||||||
binding.shareBtn.setOnClickListener {
|
binding.shareBtn.setOnClickListener {
|
||||||
val item = items[bindingAdapterPosition]
|
val item = items[bindingAdapterPosition]
|
||||||
c.shareLink(item.getLinkDecoded(), item.getTitleDecoded())
|
c.shareLink(item.getLinkDecoded(), item.title.getHtmlDecoded())
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.browserBtn.setOnClickListener {
|
binding.browserBtn.setOnClickListener {
|
||||||
|
@ -14,6 +14,9 @@ import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop
|
|||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getIcon
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getThumbnail
|
||||||
import com.amulyakhare.textdrawable.TextDrawable
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
import com.amulyakhare.textdrawable.util.ColorGenerator
|
import com.amulyakhare.textdrawable.util.ColorGenerator
|
||||||
import org.kodein.di.DI
|
import org.kodein.di.DI
|
||||||
@ -45,7 +48,7 @@ class ItemListAdapter(
|
|||||||
with(holder) {
|
with(holder) {
|
||||||
val itm = items[position]
|
val itm = items[position]
|
||||||
|
|
||||||
binding.title.text = itm.getTitleDecoded()
|
binding.title.text = itm.title.getHtmlDecoded()
|
||||||
|
|
||||||
binding.title.setOnTouchListener(LinkOnTouchListener())
|
binding.title.setOnTouchListener(LinkOnTouchListener())
|
||||||
|
|
||||||
@ -56,13 +59,13 @@ class ItemListAdapter(
|
|||||||
if (itm.getThumbnail(repository.baseUrl).isEmpty()) {
|
if (itm.getThumbnail(repository.baseUrl).isEmpty()) {
|
||||||
|
|
||||||
if (itm.getIcon(repository.baseUrl).isEmpty()) {
|
if (itm.getIcon(repository.baseUrl).isEmpty()) {
|
||||||
val color = generator.getColor(itm.getSourceTitle())
|
val color = generator.getColor(itm.title.getHtmlDecoded())
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.getSourceTitle().toTextDrawableString(c), color)
|
.build(itm.title.getHtmlDecoded().toTextDrawableString(), color)
|
||||||
|
|
||||||
binding.itemImage.setImageDrawable(drawable)
|
binding.itemImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
|
@ -10,13 +10,13 @@ import androidx.constraintlayout.widget.ConstraintLayout
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBinding
|
import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBinding
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.getIcon
|
import bou.amine.apps.readerforselfossv2.android.model.toTextDrawableString
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.getTitleDecoded
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.Config
|
import bou.amine.apps.readerforselfossv2.android.utils.Config
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.toTextDrawableString
|
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getIcon
|
||||||
import com.amulyakhare.textdrawable.TextDrawable
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
import com.amulyakhare.textdrawable.util.ColorGenerator
|
import com.amulyakhare.textdrawable.util.ColorGenerator
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -49,19 +49,19 @@ class SourcesListAdapter(
|
|||||||
config = Config()
|
config = Config()
|
||||||
|
|
||||||
if (itm.getIcon(repository.baseUrl).isEmpty()) {
|
if (itm.getIcon(repository.baseUrl).isEmpty()) {
|
||||||
val color = generator.getColor(itm.getTitleDecoded())
|
val color = generator.getColor(itm.title.getHtmlDecoded())
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.getTitleDecoded().toTextDrawableString(c), color)
|
.build(itm.title.getHtmlDecoded().toTextDrawableString(), color)
|
||||||
binding.itemImage.setImageDrawable(drawable)
|
binding.itemImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
c.circularBitmapDrawable(config, itm.getIcon(repository.baseUrl), binding.itemImage)
|
c.circularBitmapDrawable(config, itm.getIcon(repository.baseUrl), binding.itemImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.sourceTitle.text = itm.getTitleDecoded()
|
binding.sourceTitle.text = itm.title.getHtmlDecoded()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
@ -32,6 +32,9 @@ import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStrea
|
|||||||
import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth
|
import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth
|
||||||
import bou.amine.apps.readerforselfossv2.repository.Repository
|
import bou.amine.apps.readerforselfossv2.repository.Repository
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getImages
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getThumbnail
|
||||||
import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString
|
import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
@ -109,7 +112,7 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
|
|
||||||
url = item.getLinkDecoded()
|
url = item.getLinkDecoded()
|
||||||
contentText = item.content
|
contentText = item.content
|
||||||
contentTitle = item.getTitleDecoded()
|
contentTitle = item.title.getHtmlDecoded()
|
||||||
contentImage = item.getThumbnail(repository.baseUrl)
|
contentImage = item.getThumbnail(repository.baseUrl)
|
||||||
contentSource = item.sourceAndDateText(repository.dateUtils)
|
contentSource = item.sourceAndDateText(repository.dateUtils)
|
||||||
allImages = item.getImages()
|
allImages = item.getImages()
|
||||||
@ -123,7 +126,6 @@ class ArticleFragment : Fragment(), DIAware {
|
|||||||
typeface = try {
|
typeface = try {
|
||||||
ResourcesCompat.getFont(requireContext(), resId)!!
|
ResourcesCompat.getFont(requireContext(), resId)!!
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
// ACRA.getErrorReporter().maybeHandleSilentException(Throwable("Font loading issue: ${e.message}"), requireContext())
|
|
||||||
// Just to be sure
|
// Just to be sure
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -1,43 +1,12 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.model
|
package bou.amine.apps.readerforselfossv2.android.model
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
|
||||||
import android.text.Html
|
|
||||||
import android.webkit.URLUtil
|
import android.webkit.URLUtil
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getImages
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import org.jsoup.Jsoup
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Items extension methods
|
|
||||||
*/
|
|
||||||
fun SelfossModel.Item.getIcon(baseUrl: String): String {
|
|
||||||
return constructUrl(baseUrl, "favicons", icon)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SelfossModel.Item.getThumbnail(baseUrl: String): String {
|
|
||||||
return constructUrl(baseUrl, "thumbnails", thumbnail)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SelfossModel.Item.getImages() : ArrayList<String> {
|
|
||||||
val allImages = ArrayList<String>()
|
|
||||||
|
|
||||||
for ( image in Jsoup.parse(content).getElementsByTag("img")) {
|
|
||||||
val url = image.attr("src")
|
|
||||||
if (url.lowercase(Locale.US).contains(".jpg") ||
|
|
||||||
url.lowercase(Locale.US).contains(".jpeg") ||
|
|
||||||
url.lowercase(Locale.US).contains(".png") ||
|
|
||||||
url.lowercase(Locale.US).contains(".webp"))
|
|
||||||
{
|
|
||||||
allImages.add(url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return allImages
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
|
fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
|
||||||
val imageUrls = this.getImages()
|
val imageUrls = this.getImages()
|
||||||
@ -60,66 +29,13 @@ fun SelfossModel.Item.preloadImages(context: Context) : Boolean {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SelfossModel.Item.getTitleDecoded(): String {
|
fun String.toTextDrawableString(): String {
|
||||||
return Html.fromHtml(title).toString()
|
val textDrawable = StringBuilder()
|
||||||
}
|
for (s in this.split(" ".toRegex()).filter { it.isNotEmpty() }.toTypedArray()) {
|
||||||
|
try {
|
||||||
fun SelfossModel.Item.getSourceTitle(): String {
|
textDrawable.append(s[0])
|
||||||
return Html.fromHtml(sourcetitle).toString()
|
} catch (e: StringIndexOutOfBoundsException) {
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: maybe find a better way to handle these kind of urls
|
|
||||||
fun SelfossModel.Item.getLinkDecoded(): String {
|
|
||||||
var stringUrl: String
|
|
||||||
stringUrl =
|
|
||||||
if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
|
|
||||||
if (link.contains("&url=")) {
|
|
||||||
link.substringAfter("&url=")
|
|
||||||
} else {
|
|
||||||
this.link.replace("&", "&")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.link.replace("&", "&")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle :443 => https
|
|
||||||
if (stringUrl.contains(":443")) {
|
|
||||||
stringUrl = stringUrl.replace(":443", "").replace("http://", "https://")
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle url not starting with http
|
|
||||||
if (stringUrl.startsWith("//")) {
|
|
||||||
stringUrl = "http:$stringUrl"
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sources extension methods
|
|
||||||
*/
|
|
||||||
|
|
||||||
fun SelfossModel.Source.getIcon(baseUrl: String): String {
|
|
||||||
return constructUrl(baseUrl, "favicons", icon)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SelfossModel.Source.getTitleDecoded(): String {
|
|
||||||
return Html.fromHtml(title).toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common methods
|
|
||||||
*/
|
|
||||||
private fun constructUrl(baseUrl: String, path: String, file: String?): String {
|
|
||||||
return if (file == null || file == "null" || file.isEmpty()) {
|
|
||||||
""
|
|
||||||
} else {
|
|
||||||
val baseUriBuilder = Uri.parse(baseUrl).buildUpon()
|
|
||||||
baseUriBuilder.appendPath(path).appendPath(file)
|
|
||||||
|
|
||||||
baseUriBuilder.toString()
|
|
||||||
}
|
}
|
||||||
|
return textDrawable.toString()
|
||||||
}
|
}
|
@ -1,29 +0,0 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.utils
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.getSourceTitle
|
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
|
||||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
|
||||||
import bou.amine.apps.readerforselfossv2.utils.parseRelativeDate
|
|
||||||
|
|
||||||
fun String.toTextDrawableString(c: Context): String {
|
|
||||||
val textDrawable = StringBuilder()
|
|
||||||
for (s in this.split(" ".toRegex()).filter { it.isNotEmpty() }.toTypedArray()) {
|
|
||||||
try {
|
|
||||||
textDrawable.append(s[0])
|
|
||||||
} catch (e: StringIndexOutOfBoundsException) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return textDrawable.toString()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SelfossModel.Item.sourceAndDateText(dateUtils: DateUtils): String {
|
|
||||||
val formattedDate = parseRelativeDate(dateUtils)
|
|
||||||
|
|
||||||
return getSourceTitle() + formattedDate
|
|
||||||
}
|
|
||||||
|
|
||||||
fun SelfossModel.Item.toggleStar(): SelfossModel.Item {
|
|
||||||
this.starred = !this.starred
|
|
||||||
return this
|
|
||||||
}
|
|
@ -18,7 +18,6 @@ import android.widget.Toast
|
|||||||
import androidx.browser.customtabs.CustomTabsIntent
|
import androidx.browser.customtabs.CustomTabsIntent
|
||||||
import bou.amine.apps.readerforselfossv2.android.R
|
import bou.amine.apps.readerforselfossv2.android.R
|
||||||
import bou.amine.apps.readerforselfossv2.android.ReaderActivity
|
import bou.amine.apps.readerforselfossv2.android.ReaderActivity
|
||||||
import bou.amine.apps.readerforselfossv2.android.model.getLinkDecoded
|
|
||||||
import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper
|
import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp
|
import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.utils
|
|
||||||
|
|
||||||
import android.content.res.Resources
|
|
||||||
|
|
||||||
val Int.toPx: Int
|
|
||||||
get() = (this * Resources.getSystem().displayMetrics.density).toInt()
|
|
||||||
|
|
||||||
val Int.toDp: Int
|
|
||||||
get() = (this / Resources.getSystem().displayMetrics.density).toInt()
|
|
@ -1,6 +1,5 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.utils
|
package bou.amine.apps.readerforselfossv2.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.text.format.DateUtils
|
import android.text.format.DateUtils
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
|
@ -1,8 +1,51 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.utils
|
package bou.amine.apps.readerforselfossv2.utils
|
||||||
|
|
||||||
|
import android.net.Uri
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
actual fun String.getHtmlDecoded(): String {
|
actual fun String.getHtmlDecoded(): String {
|
||||||
return Html.fromHtml(this).toString()
|
return Html.fromHtml(this).toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getIcon(baseUrl: String): String {
|
||||||
|
return constructUrl(baseUrl, "favicons", icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getThumbnail(baseUrl: String): String {
|
||||||
|
return constructUrl(baseUrl, "thumbnails", thumbnail)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getImages(): ArrayList<String> {
|
||||||
|
val allImages = ArrayList<String>()
|
||||||
|
|
||||||
|
for ( image in Jsoup.parse(content).getElementsByTag("img")) {
|
||||||
|
val url = image.attr("src")
|
||||||
|
if (url.lowercase(Locale.US).contains(".jpg") ||
|
||||||
|
url.lowercase(Locale.US).contains(".jpeg") ||
|
||||||
|
url.lowercase(Locale.US).contains(".png") ||
|
||||||
|
url.lowercase(Locale.US).contains(".webp"))
|
||||||
|
{
|
||||||
|
allImages.add(url)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return allImages
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Source.getIcon(baseUrl: String): String {
|
||||||
|
return constructUrl(baseUrl, "favicons", icon)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun constructUrl(baseUrl: String, path: String, file: String?): String {
|
||||||
|
return if (file == null || file == "null" || file.isEmpty()) {
|
||||||
|
""
|
||||||
|
} else {
|
||||||
|
val baseUriBuilder = Uri.parse(baseUrl).buildUpon()
|
||||||
|
baseUriBuilder.appendPath(path).appendPath(file)
|
||||||
|
|
||||||
|
baseUriBuilder.toString()
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.model
|
package bou.amine.apps.readerforselfossv2.model
|
||||||
|
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
||||||
|
import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
class SelfossModel {
|
class SelfossModel {
|
||||||
@ -67,5 +69,40 @@ class SelfossModel {
|
|||||||
val link: String,
|
val link: String,
|
||||||
val sourcetitle: String,
|
val sourcetitle: String,
|
||||||
val tags: List<String>
|
val tags: List<String>
|
||||||
)
|
) {
|
||||||
|
// TODO: maybe find a better way to handle these kind of urls
|
||||||
|
fun getLinkDecoded(): String {
|
||||||
|
var stringUrl: String
|
||||||
|
stringUrl =
|
||||||
|
if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
|
||||||
|
if (link.contains("&url=")) {
|
||||||
|
link.substringAfter("&url=")
|
||||||
|
} else {
|
||||||
|
this.link.replace("&", "&")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.link.replace("&", "&")
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle :443 => https
|
||||||
|
if (stringUrl.contains(":443")) {
|
||||||
|
stringUrl = stringUrl.replace(":443", "").replace("http://", "https://")
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle url not starting with http
|
||||||
|
if (stringUrl.startsWith("//")) {
|
||||||
|
stringUrl = "http:$stringUrl"
|
||||||
|
}
|
||||||
|
|
||||||
|
return stringUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
fun sourceAndDateText(dateUtils: DateUtils): String =
|
||||||
|
this.title.getHtmlDecoded() + dateUtils.parseRelativeDate(this.datetime)
|
||||||
|
|
||||||
|
fun toggleStar(): Item {
|
||||||
|
this.starred = !this.starred
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -6,9 +6,6 @@ import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
|||||||
fun SelfossModel.Item.parseDate(dateUtils: DateUtils): Long =
|
fun SelfossModel.Item.parseDate(dateUtils: DateUtils): Long =
|
||||||
dateUtils.parseDate(this.datetime)
|
dateUtils.parseDate(this.datetime)
|
||||||
|
|
||||||
fun SelfossModel.Item.parseRelativeDate(dateUtils: DateUtils): String =
|
|
||||||
dateUtils.parseRelativeDate(this.datetime)
|
|
||||||
|
|
||||||
expect class DateUtils(apiMajorVersion: Int) {
|
expect class DateUtils(apiMajorVersion: Int) {
|
||||||
fun parseDate(dateString: String): Long
|
fun parseDate(dateString: String): Long
|
||||||
|
|
||||||
|
@ -1,3 +1,15 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.utils
|
package bou.amine.apps.readerforselfossv2.utils
|
||||||
|
|
||||||
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
|
||||||
expect fun String.getHtmlDecoded(): String
|
expect fun String.getHtmlDecoded(): String
|
||||||
|
|
||||||
|
expect fun SelfossModel.Item.getIcon(baseUrl: String): String
|
||||||
|
|
||||||
|
expect fun SelfossModel.Item.getThumbnail(baseUrl: String): String
|
||||||
|
|
||||||
|
expect fun SelfossModel.Item.getImages(): ArrayList<String>
|
||||||
|
|
||||||
|
expect fun SelfossModel.Source.getIcon(baseUrl: String): String
|
||||||
|
|
||||||
|
expect fun constructUrl(baseUrl: String, path: String, file: String?): String
|
@ -1,5 +1,27 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.utils
|
package bou.amine.apps.readerforselfossv2.utils
|
||||||
|
|
||||||
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
|
||||||
actual fun String.getHtmlDecoded(): String {
|
actual fun String.getHtmlDecoded(): String {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getIcon(baseUrl: String): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getThumbnail(baseUrl: String): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getImages(): ArrayList<String> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Source.getIcon(baseUrl: String): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun constructUrl(baseUrl: String, path: String, file: String?): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
@ -1,5 +1,27 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.utils
|
package bou.amine.apps.readerforselfossv2.utils
|
||||||
|
|
||||||
|
import bou.amine.apps.readerforselfossv2.model.SelfossModel
|
||||||
|
|
||||||
actual fun String.getHtmlDecoded(): String {
|
actual fun String.getHtmlDecoded(): String {
|
||||||
TODO("Not yet implemented")
|
TODO("Not yet implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getIcon(baseUrl: String): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getThumbnail(baseUrl: String): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Item.getImages(): ArrayList<String> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun SelfossModel.Source.getIcon(baseUrl: String): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
actual fun constructUrl(baseUrl: String, path: String, file: String?): String {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user