Compare commits
	
		
			9 Commits
		
	
	
		
			v124010032
			...
			v124030731
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					f24609c143 | ||
| 
						 | 
					b94d7dc537 | ||
| 
						 | 
					41910cc4cd | ||
| 
						 | 
					db166ca9d4 | ||
| 
						 | 
					db0d5a4a85 | ||
| 
						 | 
					3bc0d7cf95 | ||
| 
						 | 
					8f464d95fd | ||
| 
						 | 
					5ccd6a3368 | ||
| 
						 | 
					cdbded246e | 
							
								
								
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -1,3 +1,32 @@
 | 
			
		||||
**v124020451**
 | 
			
		||||
 | 
			
		||||
- fix: Fixed handling of position in card adapter.
 | 
			
		||||
- Changelog for v124010301 [CI SKIP]
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
**v124010301**
 | 
			
		||||
 | 
			
		||||
- fix: This may fix the oom errors.
 | 
			
		||||
- Changelog for v124010191 [CI SKIP]
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
**v124010191**
 | 
			
		||||
 | 
			
		||||
- fix: moving listeners.
 | 
			
		||||
- chore: removed a useless log.
 | 
			
		||||
- Changelog for v124010032 [CI SKIP]
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
**v124010032**
 | 
			
		||||
 | 
			
		||||
- fix: Another date format thing.
 | 
			
		||||
- Changelog for v124010031 [CI SKIP]
 | 
			
		||||
 | 
			
		||||
--------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
**v124010031**
 | 
			
		||||
 | 
			
		||||
- fix: Checking if selfoss instance.
 | 
			
		||||
 
 | 
			
		||||
@@ -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,16 +47,57 @@ 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,
 | 
			
		||||
    ) {
 | 
			
		||||
        with(holder) {
 | 
			
		||||
            val itm = items[position]
 | 
			
		||||
            val itm = items[holder.bindingAdapterPosition]
 | 
			
		||||
 | 
			
		||||
            handleClickListeners(holder.bindingAdapterPosition)
 | 
			
		||||
            handleLinkOpening(holder.bindingAdapterPosition)
 | 
			
		||||
 | 
			
		||||
            binding.favButton.isSelected = itm.starred
 | 
			
		||||
            if (appSettingsService.getPublicAccess()) {
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -44,7 +45,17 @@ class ItemListAdapter(
 | 
			
		||||
        position: Int,
 | 
			
		||||
    ) {
 | 
			
		||||
        with(holder) {
 | 
			
		||||
            val itm = items[position]
 | 
			
		||||
            val itm = items[holder.bindingAdapterPosition]
 | 
			
		||||
 | 
			
		||||
            binding.root.setOnClickListener {
 | 
			
		||||
                repository.setReaderItems(items)
 | 
			
		||||
                c.openItemUrl(
 | 
			
		||||
                    holder.bindingAdapterPosition,
 | 
			
		||||
                    items[holder.bindingAdapterPosition].getLinkDecoded(),
 | 
			
		||||
                    appSettingsService.isArticleViewerEnabled(),
 | 
			
		||||
                    app,
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            binding.title.text = itm.title.getHtmlDecoded()
 | 
			
		||||
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -89,6 +89,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
 | 
			
		||||
        if (repository.displayedItems == ItemType.UNREAD) {
 | 
			
		||||
            items.remove(item)
 | 
			
		||||
            notifyItemRemoved(position)
 | 
			
		||||
            notifyItemRangeChanged(position, itemCount)
 | 
			
		||||
            updateItems(items)
 | 
			
		||||
        } else {
 | 
			
		||||
            notifyItemChanged(position)
 | 
			
		||||
 
 | 
			
		||||
@@ -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)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ actual class DateUtils {
 | 
			
		||||
                        throw Exception("Unrecognized format for $dateString")
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (e: Exception) {
 | 
			
		||||
                    Napier.e(e.stackTraceToString(), tag = "DateUtils.parseDate")
 | 
			
		||||
                    Napier.e("parseDate failed", e, tag = "DateUtils.parseDate")
 | 
			
		||||
                    "1991-03-18T03:00:00"
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -422,7 +422,7 @@ class Repository(
 | 
			
		||||
                val response = api.login()
 | 
			
		||||
                result = response.isSuccess == true
 | 
			
		||||
            } catch (cause: Throwable) {
 | 
			
		||||
                Napier.e(cause.stackTraceToString(), tag = "RepositoryImpl.login")
 | 
			
		||||
                Napier.e("login failed", cause, tag = "RepositoryImpl.login")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result
 | 
			
		||||
@@ -436,7 +436,7 @@ class Repository(
 | 
			
		||||
                // a random rss feed, that would throw a NoTransformationFoundException
 | 
			
		||||
                fetchFailed = !api.getItemsWithoutCatch().success
 | 
			
		||||
            } catch (e: Throwable) {
 | 
			
		||||
                Napier.e(e.stackTraceToString(), tag = "RepositoryImpl.shouldBeSelfossInstance")
 | 
			
		||||
                Napier.e("checkIfFetchFails failed", e, tag = "RepositoryImpl.shouldBeSelfossInstance")
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -451,7 +451,7 @@ class Repository(
 | 
			
		||||
                    Napier.e("Couldn't logout.", tag = "RepositoryImpl.logout")
 | 
			
		||||
                }
 | 
			
		||||
            } catch (cause: Throwable) {
 | 
			
		||||
                Napier.e(cause.stackTraceToString(), tag = "RepositoryImpl.logout")
 | 
			
		||||
                Napier.e("logout failed", cause, tag = "RepositoryImpl.logout")
 | 
			
		||||
            }
 | 
			
		||||
            appSettingsService.clearAll()
 | 
			
		||||
        } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -441,7 +441,7 @@ class AppSettingsService(acraSenderServiceProcess: Boolean = false) {
 | 
			
		||||
        login: String,
 | 
			
		||||
        password: String,
 | 
			
		||||
    ) {
 | 
			
		||||
        val regex = """\/\/(\D+):(\D+)@""".toRegex()
 | 
			
		||||
        val regex = """\/\/(\S+):(\S+)@""".toRegex()
 | 
			
		||||
        val matchResult = regex.find(url)
 | 
			
		||||
        if (matchResult != null) {
 | 
			
		||||
            val (basicLogin, basicPassword) = matchResult.destructured
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user