Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverting paging3 migration #14968

Merged
merged 4 commits into from
Jul 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions WordPress/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -303,8 +303,6 @@ dependencies {
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion"
// ProcessLifecycleOwner
implementation "androidx.lifecycle:lifecycle-process:$lifecycleVersion"
// Paging Library
implementation("androidx.paging:paging-runtime-ktx:$pagingVersion")

testImplementation("androidx.arch.core:core-testing:$androidxArchCoreVersion", {
exclude group: 'com.android.support', module: 'support-compat'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
package org.wordpress.android.ui.comments.unified

import androidx.paging.PagingSource
import androidx.paging.PagingState
import org.wordpress.android.fluxc.model.CommentModel
import org.wordpress.android.fluxc.model.CommentStatus

class CommentPagingSource : PagingSource<Int, CommentModel>() {
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, CommentModel> {
return LoadResult.Page(
data = generateComments(params.loadSize),
prevKey = null, // Only paging forward
nextKey = null // Only one page for now
)
}

override fun getRefreshKey(state: PagingState<Int, CommentModel>): Int? {
return state.anchorPosition?.let { anchorPosition ->
val anchorPage = state.closestPageToPosition(anchorPosition)
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
}
}

// TODO for testing purposes only. Remove after attaching real data source.
@Suppress("MagicNumber")
fun generateComments(num: Int): List<CommentModel> {
val commentListItems = ArrayList<CommentModel>()

for (i in 0..num) {
val commentModel = CommentModel()
commentModel.id = i
commentModel.remoteCommentId = i.toLong()
commentModel.postTitle = "Post $i"
commentModel.authorName = "Author $i"
commentModel.authorEmail = "[email protected]"
commentModel.content = "Generated Comment Content for Comment with remote ID $i"
commentModel.authorProfileImageUrl = ""
if (i % 3 == 0) {
commentModel.status = CommentStatus.UNAPPROVED.toString()
} else {
commentModel.status = CommentStatus.APPROVED.toString()
}

commentListItems.add(commentModel)
}
return commentListItems
}
/**
* Temporarily commented out until migration between Paging 2 and 3 is sorted out.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: worth a reference to the Slack discussion, Sentry issue, and past PRs here to track it when we get back to it? 🤔

*/
class CommentPagingSource {
// : PagingSource<Int, CommentModel>() {
// override suspend fun load(params: LoadParams<Int>): LoadResult<Int, CommentModel> {
// return LoadResult.Page(
// data = generateComments(params.loadSize),
// prevKey = null, // Only paging forward
// nextKey = null // Only one page for now
// )
// }
//
// override fun getRefreshKey(state: PagingState<Int, CommentModel>): Int? {
// return state.anchorPosition?.let { anchorPosition ->
// val anchorPage = state.closestPageToPosition(anchorPosition)
// anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1)
// }
// }
//
// // TODO for testing purposes only. Remove after attaching real data source.
// @Suppress("MagicNumber")
// fun generateComments(num: Int): List<CommentModel> {
// val commentListItems = ArrayList<CommentModel>()
// var startTimestamp = System.currentTimeMillis() / 1000 - (30000 * num)
//
// for (i in 0..num) {
// val commentModel = CommentModel()
// commentModel.id = i
// commentModel.remoteCommentId = i.toLong()
// commentModel.postTitle = "Post $i"
// commentModel.authorName = "Author $i"
// commentModel.authorEmail = "[email protected]"
// commentModel.content = "Generated <b>Comment</b> <i>Content</i> for Comment with remote ID $i"
// startTimestamp -= 30000
// commentModel.publishedTimestamp = startTimestamp
// commentModel.datePublished = DateTimeUtils.iso8601FromDate(Date(startTimestamp * 1000))
// commentModel.authorProfileImageUrl = ""
// if (i % 3 == 0) {
// commentModel.status = CommentStatus.UNAPPROVED.toString()
// commentModel.authorProfileImageUrl =
// "https://0.gravatar.com/avatar/cec64efa352617c35743d8ed233ab410?s=96&d=identicon&r=G"
// } else {
// commentModel.status = CommentStatus.APPROVED.toString()
// commentModel.authorProfileImageUrl =
// "https://0.gravatar.com/avatar/cdc72cf084621e5cf7e42913f3197c13?s=256&d=identicon&r=G"
// }
//
// commentListItems.add(commentModel)
// }
// return commentListItems
// }
}
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
package org.wordpress.android.ui.comments.unified

import android.content.Context
import android.view.ViewGroup
import androidx.paging.PagingDataAdapter
import org.wordpress.android.WordPress
import org.wordpress.android.ui.comments.unified.UnifiedCommentListItem.Comment
import org.wordpress.android.ui.comments.unified.UnifiedCommentListItem.CommentListItemType.COMMENT
import org.wordpress.android.ui.comments.unified.UnifiedCommentListItem.CommentListItemType.SUB_HEADER
import org.wordpress.android.ui.comments.unified.UnifiedCommentListItem.SubHeader
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.image.ImageManager
import javax.inject.Inject

class UnifiedCommentListAdapter(context: Context) :
PagingDataAdapter<UnifiedCommentListItem, UnifiedCommentListViewHolder<*>>(
DIFF_CALLBACK
) {
@Inject lateinit var imageManager: ImageManager
@Inject lateinit var uiHelpers: UiHelpers

init {
(context.applicationContext as WordPress).component().inject(this)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UnifiedCommentListViewHolder<*> {
return when (viewType) {
SUB_HEADER.ordinal -> UnifiedCommentSubHeaderViewHolder(parent)
COMMENT.ordinal -> UnifiedCommentViewHolder(parent, imageManager, uiHelpers)
else -> throw IllegalArgumentException("Unexpected view holder in UnifiedCommentListAdapter")
}
}

override fun onBindViewHolder(holder: UnifiedCommentListViewHolder<*>, position: Int) {
if (holder is UnifiedCommentSubHeaderViewHolder) {
holder.bind((getItem(position) as SubHeader))
} else if (holder is UnifiedCommentViewHolder) {
holder.bind(getItem(position) as Comment)
}
}

override fun getItemViewType(position: Int): Int {
return getItem(position)!!.type.ordinal
}

companion object {
private val DIFF_CALLBACK = UnifiedCommentsListDiffCallback()
}
/**
* Temporarily commented out untill migration between Paging 2 and 3 is sorted out.
*/
class UnifiedCommentListAdapter(context: Context) {
// : PagingDataAdapter<UnifiedCommentListItem,
// UnifiedCommentListViewHolder<*>>(
// diffCallback
// ) {
// init {
// (context.applicationContext as WordPress).component().inject(this)
// }
//
// override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UnifiedCommentListViewHolder<*> {
// return when (viewType) {
// SUB_HEADER.ordinal -> UnifiedCommentSubHeaderViewHolder(parent)
// COMMENT.ordinal -> UnifiedCommentViewHolder(
// parent,
// imageManager,
// uiHelpers,
// commentListUiUtils,
// resourceProvider,
// gravatarUtilsWrapper
// )
// else -> throw IllegalArgumentException("Unexpected view holder in UnifiedCommentListAdapter")
// }
// }
//
// override fun onBindViewHolder(holder: UnifiedCommentListViewHolder<*>, position: Int) {
// if (holder is UnifiedCommentSubHeaderViewHolder) {
// holder.bind((getItem(position) as SubHeader))
// } else if (holder is UnifiedCommentViewHolder) {
// holder.bind(getItem(position) as Comment)
// }
// }
//
// override fun getItemViewType(position: Int): Int {
// return getItem(position)!!.type.ordinal
// }
//
// companion object {
// private val diffCallback = UnifiedCommentsListDiffCallback()
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.coroutines.flow.collectLatest
import org.wordpress.android.R
import org.wordpress.android.WordPress
import org.wordpress.android.databinding.CommentListFragmentBinding
import org.wordpress.android.ui.comments.CommentListItemDecoration
import javax.inject.Inject

/**
* Temporarily commented out until migration between Paging 2 and 3 is sorted out.
*/
class UnifiedCommentListFragment : Fragment(R.layout.comment_list_fragment) {
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory

private lateinit var viewModel: UnifiedCommentListViewModel
// private lateinit var adapter: UnifiedCommentListAdapter

private var binding: CommentListFragmentBinding? = null

Expand All @@ -37,18 +39,35 @@ class UnifiedCommentListFragment : Fragment(R.layout.comment_list_fragment) {
private fun CommentListFragmentBinding.setupContentViews() {
val layoutManager = LinearLayoutManager(context)
commentsRecyclerView.layoutManager = layoutManager
commentsRecyclerView.addItemDecoration(CommentListItemDecoration(commentsRecyclerView.context))
commentsRecyclerView.adapter = UnifiedCommentListAdapter(requireContext())
commentsRecyclerView.addItemDecoration(UnifiedCommentListItemDecoration(commentsRecyclerView.context))

// adapter = UnifiedCommentListAdapter(requireContext())
// commentsRecyclerView.adapter = adapter
}

private fun CommentListFragmentBinding.setupObservers() {
lifecycleScope.launchWhenStarted {
viewModel.commentListItems.collectLatest { pagingData ->
commentsRecyclerView.adapter?.let { it -> (it as UnifiedCommentListAdapter).submitData(pagingData) }
}
// viewModel.uiState.collect { uiState ->
// setupCommentsList(uiState.commentsListUiModel)
// }
}
}

// private fun CommentListFragmentBinding.setupCommentsList(commentsListUiModel: CommentsListUiModel) {
// when (commentsListUiModel) {
// is CommentsListUiModel.Data -> {
// adapter.submitData(lifecycle, commentsListUiModel.pagingData)
// }
// else -> {
// }
// }
// }

override fun onDestroyView() {
super.onDestroyView()
binding = null
}
Comment on lines +66 to +69
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see this part being added in the diff of the cherry-picked commit – https://github.com/wordpress-mobile/WordPress-Android/pull/14949/files#diff-d3f669617284dbfa52ea7b4aeb770607c0f206258a309d4140a8a417153a1b02L65, but I see it was already there back then tho.
Just double-checking this re-addition is thus intentional given this was not part of the release/17.6 branch when we did 17.6 back then.


companion object {
fun newInstance(): UnifiedCommentListFragment {
val args = Bundle()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.wordpress.android.ui.comments.unified
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole file was not part of the other PR. Is this file addition expected there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as mentioned in the PR description

NOTE: code that was cherry picked from 17.7 was slightly ahead respect the original code in 17.6. This required adding the UnifiedCommentListItemDecoration that was added in 17.7. All this code is behind a feature flag, so as far as it compiles and we confirm the fix works we should be ok.

being the code behind a feature flag AFAIU if it compiles it should not have an impact since it is not run and we removed the dependency on the paging 3 lib (happy to have your thoughts on this as well @ashiagr 🙇 )

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it behind a feature flag + there are no compilation issues (and we need the new file after the latest changes since last fix) + no fast scrolling/ refresh issues, so 👍 from me.


import android.R.attr
import android.content.Context
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ItemDecoration
import androidx.recyclerview.widget.RecyclerView.State
import org.wordpress.android.R.dimen
import org.wordpress.android.util.RtlUtils
import kotlin.math.roundToInt

/**
* CommentListItemDecoration adds margin to the start of the divider and skipp drawing divider for list sub-headers.
* Based on DividerItemDecoration.
*/
class UnifiedCommentListItemDecoration(val context: Context) : ItemDecoration() {
private val divider: Drawable?
private val bounds = Rect()
private var dividerStartOffset = 0

override fun onDraw(canvas: Canvas, parent: RecyclerView, state: State) {
if (parent.layoutManager == null || divider == null) {
return
}
canvas.save()
val left: Int
val right: Int
if (parent.clipToPadding) {
left = parent.paddingStart
right = parent.width - parent.paddingEnd
canvas.clipRect(
left, parent.paddingTop, right,
parent.height - parent.paddingBottom
)
} else {
left = 0
right = parent.width
}
val childCount = parent.childCount
for (i in 0 until childCount) {
val child = parent.getChildAt(i)
val viewHolder = parent.getChildViewHolder(child)
if (viewHolder !is UnifiedCommentSubHeaderViewHolder) {
parent.getDecoratedBoundsWithMargins(child, bounds)
val bottom = bounds.bottom + child.translationY.roundToInt()
val top = bottom - divider.intrinsicHeight
if (RtlUtils.isRtl(context)) {
divider.setBounds(left, top, right - dividerStartOffset, bottom)
} else {
divider.setBounds(left + dividerStartOffset, top, right, bottom)
}
divider.draw(canvas)
}
}
canvas.restore()
}

override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: State
) {
if (divider == null) {
outRect[0, 0, 0] = 0
return
}
val viewHolder = parent.getChildViewHolder(view)
if (viewHolder is UnifiedCommentSubHeaderViewHolder) {
outRect.setEmpty()
} else {
outRect[0, 0, 0] = divider.intrinsicHeight
}
}

companion object {
private val ATTRS = intArrayOf(attr.listDivider)
}

init {
val attrs = context.obtainStyledAttributes(ATTRS)
divider = attrs.getDrawable(0)
attrs.recycle()
dividerStartOffset = context.resources.getDimensionPixelOffset(dimen.comment_list_divider_start_offset)
}
}
Loading