rewrite threads with Kotlin & coroutines (#2617)
* initial class setup * handle events and filters * handle status state changes * code formatting * fix status filtering * cleanup code a bit * implement removeAllByAccountId * move toolbar into fragment, implement menu * error and load state handling * fix pull to refresh * implement reveal button * use requireContext() instead of context!! * jump to detailed status * add ViewThreadViewModelTest * fix ktlint * small code improvements (thx charlag) * add testcase for toggleRevealButton * add more state change testcases to ViewThreadViewModel
This commit is contained in:
parent
607f448eb3
commit
741461acde
24 changed files with 1446 additions and 999 deletions
|
|
@ -21,12 +21,12 @@ import com.keylesspalace.tusky.viewdata.StatusViewData;
|
|||
import java.text.DateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
||||
private TextView reblogs;
|
||||
private TextView favourites;
|
||||
private View infoDivider;
|
||||
public class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
||||
private final TextView reblogs;
|
||||
private final TextView favourites;
|
||||
private final View infoDivider;
|
||||
|
||||
StatusDetailedViewHolder(View view) {
|
||||
public StatusDetailedViewHolder(View view) {
|
||||
super(view);
|
||||
reblogs = view.findViewById(R.id.status_reblogs);
|
||||
favourites = view.findViewById(R.id.status_favourites);
|
||||
|
|
|
|||
|
|
@ -1,129 +0,0 @@
|
|||
/* Copyright 2021 Tusky Contributors
|
||||
*
|
||||
* This file is a part of Tusky.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Tusky is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Tusky; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
package com.keylesspalace.tusky.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.keylesspalace.tusky.R
|
||||
import com.keylesspalace.tusky.interfaces.StatusActionListener
|
||||
import com.keylesspalace.tusky.util.StatusDisplayOptions
|
||||
import com.keylesspalace.tusky.viewdata.StatusViewData
|
||||
|
||||
class ThreadAdapter(
|
||||
private val statusDisplayOptions: StatusDisplayOptions,
|
||||
private val statusActionListener: StatusActionListener
|
||||
) : RecyclerView.Adapter<StatusBaseViewHolder>() {
|
||||
private val statuses = mutableListOf<StatusViewData.Concrete>()
|
||||
var detailedStatusPosition: Int = RecyclerView.NO_POSITION
|
||||
private set
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StatusBaseViewHolder {
|
||||
return when (viewType) {
|
||||
VIEW_TYPE_STATUS -> {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_status, parent, false)
|
||||
StatusViewHolder(view)
|
||||
}
|
||||
VIEW_TYPE_STATUS_DETAILED -> {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_status_detailed, parent, false)
|
||||
StatusDetailedViewHolder(view)
|
||||
}
|
||||
else -> error("Unknown item type: $viewType")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(viewHolder: StatusBaseViewHolder, position: Int) {
|
||||
val status = statuses[position]
|
||||
viewHolder.setupWithStatus(status, statusActionListener, statusDisplayOptions)
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return if (position == detailedStatusPosition) {
|
||||
VIEW_TYPE_STATUS_DETAILED
|
||||
} else {
|
||||
VIEW_TYPE_STATUS
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = statuses.size
|
||||
|
||||
fun setStatuses(statuses: List<StatusViewData.Concrete>?) {
|
||||
this.statuses.clear()
|
||||
this.statuses.addAll(statuses!!)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun addItem(position: Int, statusViewData: StatusViewData.Concrete) {
|
||||
statuses.add(position, statusViewData)
|
||||
notifyItemInserted(position)
|
||||
}
|
||||
|
||||
fun clearItems() {
|
||||
val oldSize = statuses.size
|
||||
statuses.clear()
|
||||
detailedStatusPosition = RecyclerView.NO_POSITION
|
||||
notifyItemRangeRemoved(0, oldSize)
|
||||
}
|
||||
|
||||
fun addAll(position: Int, statuses: List<StatusViewData.Concrete>) {
|
||||
this.statuses.addAll(position, statuses)
|
||||
notifyItemRangeInserted(position, statuses.size)
|
||||
}
|
||||
|
||||
fun addAll(statuses: List<StatusViewData.Concrete>) {
|
||||
val end = statuses.size
|
||||
this.statuses.addAll(statuses)
|
||||
notifyItemRangeInserted(end, statuses.size)
|
||||
}
|
||||
|
||||
fun removeItem(position: Int) {
|
||||
statuses.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
statuses.clear()
|
||||
detailedStatusPosition = RecyclerView.NO_POSITION
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setItem(position: Int, status: StatusViewData.Concrete, notifyAdapter: Boolean) {
|
||||
statuses[position] = status
|
||||
if (notifyAdapter) {
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
fun getItem(position: Int): StatusViewData.Concrete? = statuses.getOrNull(position)
|
||||
|
||||
fun setDetailedStatusPosition(position: Int) {
|
||||
if (position != detailedStatusPosition &&
|
||||
detailedStatusPosition != RecyclerView.NO_POSITION
|
||||
) {
|
||||
val prior = detailedStatusPosition
|
||||
detailedStatusPosition = position
|
||||
notifyItemChanged(prior)
|
||||
} else {
|
||||
detailedStatusPosition = position
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val VIEW_TYPE_STATUS = 0
|
||||
private const val VIEW_TYPE_STATUS_DETAILED = 1
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue