Compare commits

..

5 Commits

Author SHA1 Message Date
8f464d95fd fix: moving listeners.
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2024-01-19 21:32:43 +01:00
5ccd6a3368 chore: removed a useless log. 2024-01-19 21:32:43 +01:00
cdbded246e Changelog for v124010032 [CI SKIP] 2024-01-03 22:16:35 +00:00
750c7758bd fix: Another date format thing.
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/promote/production Build is passing
2024-01-03 23:07:57 +01:00
22f8b14ecd Changelog for v124010031 [CI SKIP] 2024-01-03 21:46:48 +00:00
7 changed files with 124 additions and 107 deletions

View File

@ -1,3 +1,18 @@
**v124010032**
- fix: Another date format thing.
- Changelog for v124010031 [CI SKIP]
--------------------------------------------------------------------
**v124010031**
- fix: Checking if selfoss instance.
- fix: handle three characters lenght hexcode colors.
- Changelog for v123113311 [CI SKIP]
--------------------------------------------------------------------
**v123113311**
- chore: Source tracker url in the menu.

View File

@ -34,6 +34,7 @@ class ItemCardAdapter(
override var items: ArrayList<SelfossModel.Item>,
override val updateItems: (ArrayList<SelfossModel.Item>) -> Unit,
) : ItemsAdapter<ItemCardAdapter.ViewHolder>() {
private lateinit var binding: CardItemBinding
private val c: Context = app.baseContext
private val imageMaxHeight: Int =
c.resources.getDimension(R.dimen.card_image_max_height).toInt()
@ -46,10 +47,48 @@ class ItemCardAdapter(
parent: ViewGroup,
viewType: Int,
): ViewHolder {
val binding = CardItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
binding = CardItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
private fun handleClickListeners(position: Int) {
binding.favButton.setOnClickListener {
val item = items[position]
if (item.starred) {
CoroutineScope(Dispatchers.IO).launch {
repository.unstarr(item)
}
binding.favButton.isSelected = false
} else {
CoroutineScope(Dispatchers.IO).launch {
repository.starr(item)
}
binding.favButton.isSelected = true
}
}
binding.shareBtn.setOnClickListener {
val item = items[position]
c.shareLink(item.getLinkDecoded(), item.title.getHtmlDecoded())
}
binding.browserBtn.setOnClickListener {
c.openInBrowserAsNewTask(items[position])
}
}
private fun handleLinkOpening(position: Int) {
binding.root.setOnClickListener {
repository.setReaderItems(items)
c.openItemUrl(
position,
items[position].getLinkDecoded(),
appSettingsService.isArticleViewerEnabled(),
app,
)
}
}
override fun onBindViewHolder(
holder: ViewHolder,
position: Int,
@ -57,6 +96,9 @@ class ItemCardAdapter(
with(holder) {
val itm = items[position]
handleClickListeners(position)
handleLinkOpening(position)
binding.favButton.isSelected = itm.starred
if (appSettingsService.getPublicAccess()) {
binding.favButton.visibility = View.GONE
@ -96,48 +138,5 @@ class ItemCardAdapter(
return items.size
}
inner class ViewHolder(val binding: CardItemBinding) : RecyclerView.ViewHolder(binding.root) {
init {
handleClickListeners()
handleLinkOpening()
}
private fun handleClickListeners() {
binding.favButton.setOnClickListener {
val item = items[bindingAdapterPosition]
if (item.starred) {
CoroutineScope(Dispatchers.IO).launch {
repository.unstarr(item)
}
binding.favButton.isSelected = false
} else {
CoroutineScope(Dispatchers.IO).launch {
repository.starr(item)
}
binding.favButton.isSelected = true
}
}
binding.shareBtn.setOnClickListener {
val item = items[bindingAdapterPosition]
c.shareLink(item.getLinkDecoded(), item.title.getHtmlDecoded())
}
binding.browserBtn.setOnClickListener {
c.openInBrowserAsNewTask(items[bindingAdapterPosition])
}
}
private fun handleLinkOpening() {
binding.root.setOnClickListener {
repository.setReaderItems(items)
c.openItemUrl(
bindingAdapterPosition,
items[bindingAdapterPosition].getLinkDecoded(),
appSettingsService.isArticleViewerEnabled(),
app,
)
}
}
}
inner class ViewHolder(val binding: CardItemBinding) : RecyclerView.ViewHolder(binding.root)
}

View File

@ -25,6 +25,7 @@ class ItemListAdapter(
override var items: ArrayList<SelfossModel.Item>,
override val updateItems: (ArrayList<SelfossModel.Item>) -> Unit,
) : ItemsAdapter<ItemListAdapter.ViewHolder>() {
private lateinit var binding: ListItemBinding
private val c: Context = app.baseContext
override val di: DI by closestDI(app)
@ -35,7 +36,7 @@ class ItemListAdapter(
parent: ViewGroup,
viewType: Int,
): ViewHolder {
val binding = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
binding = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return ViewHolder(binding)
}
@ -46,6 +47,16 @@ class ItemListAdapter(
with(holder) {
val itm = items[position]
binding.root.setOnClickListener {
repository.setReaderItems(items)
c.openItemUrl(
bindingAdapterPosition,
items[bindingAdapterPosition].getLinkDecoded(),
appSettingsService.isArticleViewerEnabled(),
app,
)
}
binding.title.text = itm.title.getHtmlDecoded()
binding.title.setOnTouchListener(LinkOnTouchListener())
@ -68,21 +79,5 @@ class ItemListAdapter(
override fun getItemCount(): Int = items.size
inner class ViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root) {
init {
handleLinkOpening()
}
private fun handleLinkOpening() {
binding.root.setOnClickListener {
repository.setReaderItems(items)
c.openItemUrl(
bindingAdapterPosition,
items[bindingAdapterPosition].getLinkDecoded(),
appSettingsService.isArticleViewerEnabled(),
app,
)
}
}
}
inner class ViewHolder(val binding: ListItemBinding) : RecyclerView.ViewHolder(binding.root)
}

View File

@ -50,6 +50,33 @@ class SourcesListAdapter(
) {
val itm = items[position]
val deleteBtn: Button = holder.mView.findViewById(R.id.deleteBtn)
deleteBtn.setOnClickListener {
val (id, title) = items[position]
CoroutineScope(Dispatchers.IO).launch {
val successfullyDeletedSource = repository.deleteSource(id, title)
if (successfullyDeletedSource) {
items.removeAt(position)
notifyItemRemoved(position)
notifyItemRangeChanged(position, itemCount)
} else {
Toast.makeText(
app,
R.string.can_delete_source,
Toast.LENGTH_SHORT,
).show()
}
}
}
holder.mView.setOnClickListener {
val source = items[position]
repository.setSelectedSource(source)
app.startActivity(Intent(app, UpsertSourceActivity::class.java))
}
if (itm.getIcon(repository.baseUrl).isEmpty()) {
binding.itemImage.setBackgroundAndText(itm.title.getHtmlDecoded())
} else {
@ -72,38 +99,5 @@ class SourcesListAdapter(
override fun getItemCount(): Int = items.size
inner class ViewHolder(private val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
init {
handleClickListeners()
}
private fun handleClickListeners() {
val deleteBtn: Button = mView.findViewById(R.id.deleteBtn)
deleteBtn.setOnClickListener {
val (id, title) = items[bindingAdapterPosition]
CoroutineScope(Dispatchers.IO).launch {
val successfullyDeletedSource = repository.deleteSource(id, title)
if (successfullyDeletedSource) {
items.removeAt(bindingAdapterPosition)
notifyItemRemoved(bindingAdapterPosition)
notifyItemRangeChanged(bindingAdapterPosition, itemCount)
} else {
Toast.makeText(
app,
R.string.can_delete_source,
Toast.LENGTH_SHORT,
).show()
}
}
}
mView.setOnClickListener {
val source = items[bindingAdapterPosition]
repository.setSelectedSource(source)
app.startActivity(Intent(app, UpsertSourceActivity::class.java))
}
}
}
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView)
}

View File

@ -52,7 +52,6 @@ import org.kodein.di.DIAware
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import java.net.MalformedURLException
import java.net.SocketTimeoutException
import java.net.URL
import java.util.*
import java.util.concurrent.ExecutionException
@ -264,10 +263,7 @@ class ArticleFragment : Fragment(), DIAware {
} else {
openInBrowserAfterFailing()
}
} catch (e: SocketTimeoutException) {
openInBrowserAfterFailing()
} catch (e: Exception) {
e.sendSilentlyWithAcraWithName("getContentFromMercury > $url")
openInBrowserAfterFailing()
}
}

View File

@ -13,6 +13,8 @@ class DatesTest {
private val oldVersionDate = "2013-05-07 13:46:00"
private val oldVersionDateVariant = "2021-03-21 10:32:00.000000"
private val bugVersionDate = "2023-12-19T10:30:53-05:00"
@Test
fun new_version_date_should_be_parsed() {
val date = DateUtils.parseDate(newVersionDate)
@ -52,4 +54,14 @@ class DatesTest {
assertEquals(expected, date)
}
@Test
fun bug_version_variant_date_should_be_parsed() {
val date = DateUtils.parseDate(bugVersionDate)
val expected =
LocalDateTime(1991, 3, 18, 3, 0, 0, 0).toInstant(TimeZone.currentSystemDefault())
.toEpochMilliseconds()
assertEquals(expected, date)
}
}

View File

@ -1,6 +1,7 @@
package bou.amine.apps.readerforselfossv2.utils
import android.text.format.DateUtils
import io.github.aakira.napier.Napier
import kotlinx.datetime.*
actual class DateUtils {
@ -16,12 +17,17 @@ actual class DateUtils {
// For now, we handle this in a hacky way, because kotlin only accepts iso formats
actual fun parseDate(dateString: String): Long {
var isoDateString: String =
if (dateString.matches(oldVersionFormat)) {
dateString.replace(" ", "T")
} else if (dateString.matches(newVersionFormat)) {
dateString.split("+")[0]
} else {
throw Exception("Unrecognized format for $dateString")
try {
if (dateString.matches(oldVersionFormat)) {
dateString.replace(" ", "T")
} else if (dateString.matches(newVersionFormat)) {
dateString.split("+")[0]
} else {
throw Exception("Unrecognized format for $dateString")
}
} catch (e: Exception) {
Napier.e(e.stackTraceToString(), tag = "DateUtils.parseDate")
"1991-03-18T03:00:00"
}
return LocalDateTime.parse(isoDateString).toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds()