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

Move photon url logic from VH to VM #10267

Merged
merged 2 commits into from
Jul 22, 2019
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
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.ui.utils.UiString
import org.wordpress.android.util.DisplayUtils
import org.wordpress.android.util.NetworkUtils
import org.wordpress.android.util.SiteUtils
import org.wordpress.android.util.ToastUtils
import org.wordpress.android.util.WPSwipeToRefreshHelper.buildSwipeToRefreshHelper
import org.wordpress.android.util.helpers.SwipeToRefreshHelper
Expand Down Expand Up @@ -63,23 +62,11 @@ class PostListFragment : Fragment() {
private lateinit var postListType: PostListType

private lateinit var nonNullActivity: FragmentActivity
private lateinit var site: SiteModel

private val postViewHolderConfig: PostViewHolderConfig by lazy {
val displayWidth = DisplayUtils.getDisplayPixelWidth(context)
val contentSpacing = nonNullActivity.resources.getDimensionPixelSize(R.dimen.content_margin)
PostViewHolderConfig(
photonWidth = displayWidth - contentSpacing * 2,
photonHeight = nonNullActivity.resources.getDimensionPixelSize(R.dimen.reader_featured_image_height),
isPhotonCapable = SiteUtils.isPhotonCapable(site),
imageManager = imageManager
)
}

private val postListAdapter: PostListAdapter by lazy {
PostListAdapter(
context = nonNullActivity,
postViewHolderConfig = postViewHolderConfig,
imageManager = imageManager,
uiHelpers = uiHelpers
)
}
Expand All @@ -89,18 +76,12 @@ class PostListFragment : Fragment() {
nonNullActivity = checkNotNull(activity)
(nonNullActivity.application as WordPress).component().inject(this)

val site: SiteModel? = if (savedInstanceState == null) {
val nonNullIntent = checkNotNull(nonNullActivity.intent)
nonNullIntent.getSerializableExtra(WordPress.SITE) as SiteModel?
} else {
savedInstanceState.getSerializable(WordPress.SITE) as SiteModel?
}
val nonNullIntent = checkNotNull(nonNullActivity.intent)
val site: SiteModel? = nonNullIntent.getSerializableExtra(WordPress.SITE) as SiteModel?

if (site == null) {
ToastUtils.showToast(nonNullActivity, R.string.blog_not_found, ToastUtils.Duration.SHORT)
nonNullActivity.finish()
} else {
this.site = site
}
}

Expand Down Expand Up @@ -136,7 +117,13 @@ class PostListFragment : Fragment() {
val postListViewModelConnector = mainViewModel.getPostListViewModelConnector(authorFilter, postListType)

viewModel = ViewModelProviders.of(this, viewModelFactory).get<PostListViewModel>(PostListViewModel::class.java)
viewModel.start(postListViewModelConnector)

val displayWidth = DisplayUtils.getDisplayPixelWidth(context)
val contentSpacing = nonNullActivity.resources.getDimensionPixelSize(R.dimen.content_margin)
viewModel.start(
postListViewModelConnector, photonWidth = displayWidth - contentSpacing * 2,
photonHeight = nonNullActivity.resources.getDimensionPixelSize(R.dimen.reader_featured_image_height)
)

initObservers()
}
Expand Down Expand Up @@ -173,11 +160,6 @@ class PostListFragment : Fragment() {
})
}

override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
outState.putSerializable(WordPress.SITE, site)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater.inflate(R.layout.post_list_fragment, container, false)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ import androidx.annotation.LayoutRes
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import org.wordpress.android.R
import org.wordpress.android.ui.reader.utils.ReaderUtils
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.ui.utils.UiString
import org.wordpress.android.util.image.ImageManager
import org.wordpress.android.util.image.ImageType
import org.wordpress.android.viewmodel.posts.PostListItemAction
import org.wordpress.android.viewmodel.posts.PostListItemAction.MoreItem
Expand All @@ -33,7 +33,7 @@ import org.wordpress.android.widgets.WPTextView
sealed class PostListItemViewHolder(
@LayoutRes layout: Int,
parent: ViewGroup,
private val config: PostViewHolderConfig,
private val imageManager: ImageManager,
private val uiHelpers: UiHelpers
) : RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(layout, parent, false)) {
private val featuredImageView: ImageView = itemView.findViewById(R.id.image_featured)
Expand All @@ -52,9 +52,9 @@ sealed class PostListItemViewHolder(

class Standard(
parent: ViewGroup,
config: PostViewHolderConfig,
imageManager: ImageManager,
private val uiHelpers: UiHelpers
) : PostListItemViewHolder(R.layout.post_list_item, parent, config, uiHelpers) {
) : PostListItemViewHolder(R.layout.post_list_item, parent, imageManager, uiHelpers) {
private val excerptTextView: WPTextView = itemView.findViewById(R.id.excerpt)
private val actionButtons: List<PostListButton> = listOf(
itemView.findViewById(R.id.btn_primary),
Expand Down Expand Up @@ -95,9 +95,9 @@ sealed class PostListItemViewHolder(

class Compact(
parent: ViewGroup,
config: PostViewHolderConfig,
imageManager: ImageManager,
private val uiHelpers: UiHelpers
) : PostListItemViewHolder(R.layout.post_list_item_compact, parent, config, uiHelpers) {
) : PostListItemViewHolder(R.layout.post_list_item_compact, parent, imageManager, uiHelpers) {
private val moreButton: ImageButton = itemView.findViewById(R.id.more_button)

override fun onBind(item: PostListItemUiState) {
Expand Down Expand Up @@ -170,15 +170,12 @@ sealed class PostListItemViewHolder(
// Suppress blinking as the media upload progresses
return
}
if (imageUrl == null) {
if (imageUrl.isNullOrBlank()) {
featuredImageView.visibility = View.GONE
config.imageManager.cancelRequestAndClearImageView(featuredImageView)
imageManager.cancelRequestAndClearImageView(featuredImageView)
} else {
val photonUrl = ReaderUtils.getResizedImageUrl(
imageUrl, config.photonWidth, config.photonHeight, !config.isPhotonCapable
)
featuredImageView.visibility = View.VISIBLE
config.imageManager.load(featuredImageView, ImageType.PHOTO, photonUrl, ScaleType.CENTER_CROP)
imageManager.load(featuredImageView, ImageType.PHOTO, imageUrl, ScaleType.CENTER_CROP)
}
loadedFeaturedImgUrl = imageUrl
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import org.wordpress.android.ui.posts.PostListItemViewHolder
import org.wordpress.android.ui.posts.PostListViewLayoutType
import org.wordpress.android.ui.posts.PostListViewLayoutType.COMPACT
import org.wordpress.android.ui.posts.PostListViewLayoutType.STANDARD
import org.wordpress.android.ui.posts.PostViewHolderConfig
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.image.ImageManager
import org.wordpress.android.viewmodel.posts.PostListItemProgressBar
import org.wordpress.android.viewmodel.posts.PostListItemType
import org.wordpress.android.viewmodel.posts.PostListItemType.EndListIndicatorItem
Expand All @@ -30,7 +30,7 @@ private const val VIEW_TYPE_LOADING_COMPACT = 4

class PostListAdapter(
context: Context,
private val postViewHolderConfig: PostViewHolderConfig,
private val imageManager: ImageManager,
private val uiHelpers: UiHelpers
) : PagedListAdapter<PostListItemType, ViewHolder>(PostListDiffItemCallback) {
private val layoutInflater: LayoutInflater = LayoutInflater.from(context)
Expand Down Expand Up @@ -69,10 +69,10 @@ class PostListAdapter(
LoadingViewHolder(view)
}
VIEW_TYPE_POST -> {
PostListItemViewHolder.Standard(parent, postViewHolderConfig, uiHelpers)
PostListItemViewHolder.Standard(parent, imageManager, uiHelpers)
}
VIEW_TYPE_POST_COMPACT -> {
PostListItemViewHolder.Compact(parent, postViewHolderConfig, uiHelpers)
PostListItemViewHolder.Compact(parent, imageManager, uiHelpers)
}
else -> {
// Fail fast if a new view type is added so the we can handle it
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.wordpress.android.ui.reader.utils

import dagger.Reusable
import javax.inject.Inject

/**
* Injectable wrapper around ReaderUtils.
*
* ReaderUtils interface is consisted of static methods, which make the client code difficult to test/mock. Main purpose of
* this wrapper is to make testing easier.
*
*/
@Reusable
class ReaderUtilsWrapper @Inject constructor() {
fun getResizedImageUrl(imageUrl: String?, width: Int, height: Int, isPrivate: Boolean): String? =
ReaderUtils.getResizedImageUrl(imageUrl, width, height, isPrivate)
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import org.wordpress.android.ui.posts.AuthorFilterSelection.ME
import org.wordpress.android.ui.posts.PostListType.SEARCH
import org.wordpress.android.ui.posts.PostUtils
import org.wordpress.android.ui.posts.trackPostListAction
import org.wordpress.android.ui.reader.utils.ReaderUtilsWrapper
import org.wordpress.android.ui.uploads.UploadStarter
import org.wordpress.android.util.AppLog
import org.wordpress.android.util.NetworkUtilsWrapper
Expand All @@ -47,6 +48,7 @@ import org.wordpress.android.viewmodel.posts.PostListItemIdentifier.LocalPostId
import org.wordpress.android.viewmodel.posts.PostListItemType.PostListItemUiState
import javax.inject.Inject
import javax.inject.Named
import kotlin.properties.Delegates

typealias PagedPostList = PagedList<PostListItemType>

Expand All @@ -63,6 +65,7 @@ class PostListViewModel @Inject constructor(
private val listItemUiStateHelper: PostListItemUiStateHelper,
private val networkUtilsWrapper: NetworkUtilsWrapper,
private val uploadStarter: UploadStarter,
private val readerUtilsWrapper: ReaderUtilsWrapper,
@Named(UI_THREAD) private val uiDispatcher: CoroutineDispatcher,
@Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher,
connectionStatus: LiveData<ConnectionStatus>
Expand All @@ -73,6 +76,9 @@ class PostListViewModel @Inject constructor(
private var isStarted: Boolean = false
private lateinit var connector: PostListViewModelConnector

private var photonWidth by Delegates.notNull<Int>()
private var photonHeight by Delegates.notNull<Int>()

private var scrollToLocalPostId: LocalPostId? = null

private val _scrollToPosition = SingleLiveEvent<Int>()
Expand Down Expand Up @@ -113,10 +119,16 @@ class PostListViewModel @Inject constructor(
private val lifecycleRegistry = LifecycleRegistry(this)
override fun getLifecycle(): Lifecycle = lifecycleRegistry

fun start(postListViewModelConnector: PostListViewModelConnector) {
fun start(
postListViewModelConnector: PostListViewModelConnector,
photonWidth: Int,
photonHeight: Int
) {
if (isStarted) {
return
}
this.photonHeight = photonHeight
this.photonWidth = photonWidth
connector = postListViewModelConnector

if (connector.postListType != SEARCH) {
Expand Down Expand Up @@ -337,7 +349,8 @@ class PostListViewModel @Inject constructor(
unhandledConflicts = connector.doesPostHaveUnhandledConflict(post),
capabilitiesToPublish = connector.site.hasCapabilityPublishPosts,
statsSupported = isStatsSupported,
featuredImageUrl = connector.getFeaturedImageUrl(post.featuredImageId),
featuredImageUrl =
convertToPhotonUrlIfPossible(connector.getFeaturedImageUrl(post.featuredImageId)),
formattedDate = PostUtils.getFormattedDate(post),
performingCriticalAction = connector.postActionHandler.isPerformingCriticalAction(LocalId(post.id)),
onAction = { postModel, buttonType, statEvent ->
Expand All @@ -354,4 +367,12 @@ class PostListViewModel @Inject constructor(
fetchFirstPage()
}
}

private fun convertToPhotonUrlIfPossible(featuredImageUrl: String?): String? =
readerUtilsWrapper.getResizedImageUrl(
featuredImageUrl,
photonWidth,
photonHeight,
!SiteUtils.isPhotonCapable(connector.site)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import org.wordpress.android.ui.posts.PostListType.DRAFTS
import org.wordpress.android.ui.posts.PostListType.SEARCH
import org.wordpress.android.ui.uploads.UploadStarter

private const val DEFAULT_PHOTON_DIMENSIONS = -9
class PostListViewModelTest : BaseUnitTest() {
@Mock private lateinit var site: SiteModel
@Mock private lateinit var uploadStarter: UploadStarter
Expand All @@ -34,33 +35,16 @@ class PostListViewModelTest : BaseUnitTest() {
val listStore = mock<ListStore>()
val postList = mock<PagedListWrapper<PostListItemType>>()

whenever(
postList.listError
).thenReturn(mock())

whenever(
postList.isFetchingFirstPage
).thenReturn(mock())

whenever(
postList.isEmpty
).thenReturn(mock())

whenever(
postList.data
).thenReturn(mock())

whenever(
postList.isLoadingMore
).thenReturn(mock())

whenever(
listStore.getList<PostListDescriptorForXmlRpcSite, PostListItemIdentifier, PostListItemType>(
whenever(postList.listError).thenReturn(mock())
whenever(postList.isFetchingFirstPage).thenReturn(mock())
whenever(postList.isEmpty).thenReturn(mock())
whenever(postList.data).thenReturn(mock())
whenever(postList.isLoadingMore).thenReturn(mock())
whenever(listStore.getList<PostListDescriptorForXmlRpcSite, PostListItemIdentifier, PostListItemType>(
any(),
any(),
any()
)
).thenReturn(postList)
)).thenReturn(postList)

viewModel = PostListViewModel(
dispatcher = mock(),
Expand All @@ -70,6 +54,7 @@ class PostListViewModelTest : BaseUnitTest() {
listItemUiStateHelper = mock(),
networkUtilsWrapper = mock(),
uploadStarter = uploadStarter,
readerUtilsWrapper = mock(),
connectionStatus = mock(),
uiDispatcher = TEST_DISPATCHER,
bgDispatcher = TEST_DISPATCHER
Expand All @@ -78,7 +63,11 @@ class PostListViewModelTest : BaseUnitTest() {

@Test
fun `when swiping to refresh, it uploads all local drafts`() {
viewModel.start(createPostListViewModelConnector(site = site, postListType = DRAFTS))
viewModel.start(
createPostListViewModelConnector(site = site, postListType = DRAFTS),
DEFAULT_PHOTON_DIMENSIONS,
DEFAULT_PHOTON_DIMENSIONS
)

// When
viewModel.swipeToRefresh()
Expand All @@ -89,7 +78,11 @@ class PostListViewModelTest : BaseUnitTest() {

@Test
fun `empty search query should show search prompt`() {
viewModel.start(createPostListViewModelConnector(site = site, postListType = SEARCH))
viewModel.start(
createPostListViewModelConnector(site = site, postListType = SEARCH),
DEFAULT_PHOTON_DIMENSIONS,
DEFAULT_PHOTON_DIMENSIONS
)

val emptyViewStateResults = mutableListOf<PostListEmptyUiState>()

Expand Down