Skip to content

Commit

Permalink
Merge pull request #16622 from wordpress-mobile/issue/16588-remove-qs…
Browse files Browse the repository at this point in the history
…-collapsible-completed-tasks-view

Quick Start: Remove completed list from tasks checklist modal
  • Loading branch information
AjeshRPai authored May 24, 2022
2 parents c78f1cb + 9daf309 commit 32421e5
Show file tree
Hide file tree
Showing 15 changed files with 196 additions and 1,512 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,138 +2,43 @@ package org.wordpress.android.ui.quickstart

import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView.Adapter
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import org.wordpress.android.fluxc.store.QuickStartStore.QuickStartTask
import org.wordpress.android.ui.quickstart.viewholders.CompletedHeaderViewHolder
import org.wordpress.android.ui.quickstart.QuickStartFullScreenDialogFragment.QuickStartTaskCard
import org.wordpress.android.ui.quickstart.viewholders.TaskViewHolder

class QuickStartAdapter(
tasksUncompleted: MutableList<QuickStartTask?>,
tasksCompleted: MutableList<QuickStartTask?>,
isCompletedTasksListExpanded: Boolean
) : Adapter<ViewHolder>() {
private val tasks: MutableList<QuickStartTask?> = mutableListOf()
private val tasksUncompleted: MutableList<QuickStartTask?>
private val taskCompleted: MutableList<QuickStartTask?>
private var listener: OnQuickStartAdapterActionListener? = null
var isCompletedTasksListExpanded: Boolean
private set

init {
tasks.addAll(tasksUncompleted)
if (tasksCompleted.isNotEmpty()) {
tasks.add(null) // adding null where the complete tasks header simplifies a lot of logic for us
}
this.isCompletedTasksListExpanded = isCompletedTasksListExpanded
if (this.isCompletedTasksListExpanded) {
tasks.addAll(tasksCompleted)
}
this.tasksUncompleted = tasksUncompleted
this.taskCompleted = tasksCompleted
}

class QuickStartAdapter : ListAdapter<QuickStartTaskCard, ViewHolder>(QuickStartAdapterDiffCallback) {
override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int) = when (viewType) {
VIEW_TYPE_TASK -> TaskViewHolder(
parent = viewGroup,
tasks = tasks,
listener = listener
)
VIEW_TYPE_COMPLETED_TASKS_HEADER -> CompletedHeaderViewHolder(
parent = viewGroup,
onChevronRotate = this::getChevronRotation,
onChevronAnimationCompleted = this::onChevronAnimationCompleted
)
VIEW_TYPE_TASK -> TaskViewHolder(parent = viewGroup)
else -> throw IllegalArgumentException("Unexpected view type")
}

override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
when (viewHolder) {
is TaskViewHolder -> viewHolder.bind(
task = tasks[position],
isEnabled = tasksUncompleted.contains(tasks[position]),
shouldHideDivider = position == tasksUncompleted.size - 1 || position == tasks.size - 1
)
is CompletedHeaderViewHolder -> viewHolder.bind(
isCompletedTasksListExpanded = isCompletedTasksListExpanded,
taskCompletedSize = taskCompleted.size,
tasksUncompletedSize = tasksUncompleted.size
taskCard = getItem(position),
shouldHideDivider = position == itemCount - 1
)
}
}

fun updateContent(
tasksUncompleted: List<QuickStartTask?>?,
tasksCompleted: List<QuickStartTask?>
) {
val newList = mutableListOf<QuickStartTask?>()
tasksUncompleted?.let { newList.addAll(it) }
if (tasksCompleted.isNotEmpty()) {
newList.add(null)
}
if (isCompletedTasksListExpanded) {
newList.addAll(tasksCompleted)
}
taskCompleted.clear()
taskCompleted.addAll(tasksCompleted)
this.tasksUncompleted.clear()
this.tasksUncompleted.addAll(tasksUncompleted!!)
val diffResult = DiffUtil.calculateDiff(QuickStartTasksDiffCallback(tasks, newList))
tasks.clear()
tasks.addAll(newList)
diffResult.dispatchUpdatesTo(this)

// Notify adapter of each task change individually. Using notifyDataSetChanged() kills list changing animation.
for (task in tasks) {
notifyItemChanged(tasks.indexOf(task))
}
}

override fun getItemViewType(position: Int): Int {
return if (position == tasksUncompleted.size) {
VIEW_TYPE_COMPLETED_TASKS_HEADER
} else {
VIEW_TYPE_TASK
}
return VIEW_TYPE_TASK
}

override fun getItemCount(): Int {
return tasks.size
}

fun setOnTaskTappedListener(listener: OnQuickStartAdapterActionListener?) {
this.listener = listener
return currentList.size
}

private fun getChevronRotation() =
if (isCompletedTasksListExpanded) COLLAPSED_CHEVRON_ROTATION else EXPANDED_CHEVRON_ROTATION

private fun onChevronAnimationCompleted(adapterPosition: Int) {
val positionAfterHeader = adapterPosition + 1
if (isCompletedTasksListExpanded) {
tasks.removeAll(taskCompleted)
notifyItemRangeRemoved(positionAfterHeader, taskCompleted.size)
} else {
tasks.addAll(taskCompleted)
notifyItemRangeInserted(positionAfterHeader, taskCompleted.size)
}

// Update header background based after collapsed and expanded.
notifyItemChanged(adapterPosition)
isCompletedTasksListExpanded = !isCompletedTasksListExpanded
listener?.onCompletedTasksListToggled(isCompletedTasksListExpanded)
}
object QuickStartAdapterDiffCallback : DiffUtil.ItemCallback<QuickStartTaskCard>() {
override fun areItemsTheSame(oldItem: QuickStartTaskCard, updatedItem: QuickStartTaskCard) =
oldItem.task.string == updatedItem.task.string

interface OnQuickStartAdapterActionListener {
fun onSkipTaskTapped(task: QuickStartTask?)
fun onTaskTapped(task: QuickStartTask?)
fun onCompletedTasksListToggled(isExpanded: Boolean)
override fun areContentsTheSame(oldItem: QuickStartTaskCard, newItem: QuickStartTaskCard) =
oldItem == newItem
}

companion object {
private const val VIEW_TYPE_TASK = 0
private const val VIEW_TYPE_COMPLETED_TASKS_HEADER = 1
const val EXPANDED_CHEVRON_ROTATION = -180f
const val COLLAPSED_CHEVRON_ROTATION = 0f
}
}
Loading

0 comments on commit 32421e5

Please sign in to comment.