Skip to content

Commit

Permalink
WIP implement more menu using existing Reader logic
Browse files Browse the repository at this point in the history
  • Loading branch information
RenanLukas committed May 10, 2024
1 parent e5603d4 commit 91bc858
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package org.wordpress.android.ui.reader

import android.os.Bundle
import android.view.Gravity
import android.view.View
import androidx.appcompat.widget.ListPopupWindow
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.core.view.ViewCompat.animate
Expand All @@ -12,12 +14,14 @@ import androidx.lifecycle.ViewModelProvider
import com.google.android.material.snackbar.Snackbar
import dagger.hilt.android.AndroidEntryPoint
import org.wordpress.android.R
import org.wordpress.android.analytics.AnalyticsTracker
import org.wordpress.android.databinding.ReaderTagFeedFragmentLayoutBinding
import org.wordpress.android.models.ReaderTag
import org.wordpress.android.ui.ActivityLauncher
import org.wordpress.android.ui.ViewPagerFragment
import org.wordpress.android.ui.compose.theme.AppThemeWithoutBackground
import org.wordpress.android.ui.main.WPMainActivity
import org.wordpress.android.ui.reader.adapters.ReaderMenuAdapter
import org.wordpress.android.ui.reader.comments.ThreadedCommentsActionSource
import org.wordpress.android.ui.reader.discover.ReaderNavigationEvents
import org.wordpress.android.ui.reader.subfilter.SubFilterViewModel
Expand All @@ -28,6 +32,7 @@ import org.wordpress.android.ui.reader.utils.ReaderUtilsWrapper
import org.wordpress.android.ui.reader.viewmodels.tagsfeed.ReaderTagsFeedViewModel
import org.wordpress.android.ui.reader.viewmodels.tagsfeed.ReaderTagsFeedViewModel.ActionEvent
import org.wordpress.android.ui.reader.views.compose.tagsfeed.ReaderTagsFeed
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.extensions.getSerializableCompat
import org.wordpress.android.viewmodel.observeEvent
import org.wordpress.android.widgets.WPSnackbar
Expand Down Expand Up @@ -62,6 +67,9 @@ class ReaderTagsFeedFragment : ViewPagerFragment(R.layout.reader_tag_feed_fragme
@Inject
lateinit var readerTracker: ReaderTracker

@Inject
lateinit var uiHelpers: UiHelpers

// binding
private lateinit var binding: ReaderTagFeedFragmentLayoutBinding

Expand All @@ -79,6 +87,7 @@ class ReaderTagsFeedFragment : ViewPagerFragment(R.layout.reader_tag_feed_fragme
observeActionEvents()
observeNavigationEvents()
observeErrorMessageEvents()
observeOpenMoreMenuEvents()
}

private fun observeSubFilterViewModel(savedInstanceState: Bundle?) {
Expand Down Expand Up @@ -259,6 +268,29 @@ class ReaderTagsFeedFragment : ViewPagerFragment(R.layout.reader_tag_feed_fragme
}
}

private fun observeOpenMoreMenuEvents() {
viewModel.openMoreMenuEvents.observe(viewLifecycleOwner) {
val readerCardUiState = it.readerCardUiState
val blogId = readerCardUiState.blogId
val postId = readerCardUiState.postId
val anchorView = binding.composeView.findViewWithTag<View>("$blogId$postId")
readerTracker.track(AnalyticsTracker.Stat.POST_CARD_MORE_TAPPED)
val listPopup = ListPopupWindow(anchorView.context)
listPopup.width = anchorView.context.resources.getDimensionPixelSize(R.dimen.menu_item_width)
listPopup.setAdapter(ReaderMenuAdapter(anchorView.context, uiHelpers, it.readerPostCardActions))
listPopup.setDropDownGravity(Gravity.END)
listPopup.anchorView = anchorView
listPopup.isModal = true
listPopup.setOnItemClickListener { _, _, position, _ ->
listPopup.dismiss()
val item = it.readerPostCardActions[position]
item.onClicked?.invoke(postId, blogId, item.type)
}
listPopup.setOnDismissListener { readerCardUiState.onMoreDismissed.invoke(readerCardUiState) }
listPopup.show()
}
}

private fun showBookmarkSavedLocallyDialog(
bookmarkDialog: ReaderNavigationEvents.ShowBookmarkedSavedOnlyLocallyDialog
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ public enum ReaderPostListType {
TAG_FOLLOWED(ReaderTracker.SOURCE_FOLLOWING), // list posts in a followed tag
TAG_PREVIEW(ReaderTracker.SOURCE_TAG_PREVIEW), // list posts in a specific tag
BLOG_PREVIEW(ReaderTracker.SOURCE_SITE_PREVIEW), // list posts in a specific blog/feed
SEARCH_RESULTS(ReaderTracker.SOURCE_SEARCH); // list posts matching a specific search keyword or phrase
SEARCH_RESULTS(ReaderTracker.SOURCE_SEARCH), // list posts matching a specific search keyword or phrase
TAGS_FEED(ReaderTracker.SOURCE_TAGS_FEED); // list posts in the tags feed

private final String mSource;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class ReaderTagsFeedUiStateMapper @Inject constructor(
onSiteClick: (TagsFeedPostItem) -> Unit,
onPostCardClick: (TagsFeedPostItem) -> Unit,
onPostLikeClick: (TagsFeedPostItem) -> Unit,
onPostMoreMenuClick: () -> Unit,
onPostMoreMenuClick: (TagsFeedPostItem) -> Unit,
) = ReaderTagsFeedViewModel.TagFeedItem(
tagChip = ReaderTagsFeedViewModel.TagChip(
tag = tag,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,22 @@ import org.wordpress.android.datasets.wrappers.ReaderPostTableWrapper
import org.wordpress.android.models.ReaderPost
import org.wordpress.android.models.ReaderTag
import org.wordpress.android.modules.BG_THREAD
import org.wordpress.android.ui.reader.ReaderTypes
import org.wordpress.android.ui.reader.discover.FEATURED_IMAGE_HEIGHT_WIDTH_RATION
import org.wordpress.android.ui.reader.discover.PHOTON_WIDTH_QUALITY_RATION
import org.wordpress.android.ui.reader.discover.ReaderCardUiState
import org.wordpress.android.ui.reader.discover.ReaderNavigationEvents
import org.wordpress.android.ui.reader.discover.ReaderPostCardAction
import org.wordpress.android.ui.reader.discover.ReaderPostCardActionType
import org.wordpress.android.ui.reader.discover.ReaderPostCardActionsHandler
import org.wordpress.android.ui.reader.discover.ReaderPostMoreButtonUiStateBuilder
import org.wordpress.android.ui.reader.discover.ReaderPostUiStateBuilder
import org.wordpress.android.ui.reader.exceptions.ReaderPostFetchException
import org.wordpress.android.ui.reader.repository.ReaderPostRepository
import org.wordpress.android.ui.reader.repository.usecases.PostLikeUseCase
import org.wordpress.android.ui.reader.tracker.ReaderTracker
import org.wordpress.android.ui.reader.views.compose.tagsfeed.TagsFeedPostItem
import org.wordpress.android.util.DisplayUtilsWrapper
import org.wordpress.android.viewmodel.Event
import org.wordpress.android.viewmodel.ScopedViewModel
import org.wordpress.android.viewmodel.SingleLiveEvent
Expand All @@ -34,6 +43,9 @@ class ReaderTagsFeedViewModel @Inject constructor(
private val readerPostCardActionsHandler: ReaderPostCardActionsHandler,
private val postLikeUseCase: PostLikeUseCase,
private val readerPostTableWrapper: ReaderPostTableWrapper,
private val readerPostMoreButtonUiStateBuilder: ReaderPostMoreButtonUiStateBuilder,
private val readerPostUiStateBuilder: ReaderPostUiStateBuilder,
private val displayUtilsWrapper: DisplayUtilsWrapper,
) : ScopedViewModel(bgDispatcher) {
private val _uiStateFlow: MutableStateFlow<UiState> = MutableStateFlow(UiState.Initial)
val uiStateFlow: StateFlow<UiState> = _uiStateFlow
Expand All @@ -47,6 +59,9 @@ class ReaderTagsFeedViewModel @Inject constructor(
private val _errorMessageEvents = MediatorLiveData<Event<Int>>()
val errorMessageEvents: LiveData<Event<Int>> = _errorMessageEvents

private val _openMoreMenuEvents = SingleLiveEvent<MoreMenuUiState>()
val openMoreMenuEvents: LiveData<MoreMenuUiState> = _openMoreMenuEvents

private var hasInitialized = false

/**
Expand Down Expand Up @@ -269,10 +284,10 @@ class ReaderTagsFeedViewModel @Inject constructor(

private fun findTagFeedItemToUpdate(uiState: UiState.Loaded, postItemToUpdate: TagsFeedPostItem) =
uiState.data.firstOrNull { tagFeedItem ->
tagFeedItem.postList is PostList.Loaded && tagFeedItem.postList.items.firstOrNull {
it.postId == postItemToUpdate.postId && it.blogId == postItemToUpdate.blogId
} != null
}
tagFeedItem.postList is PostList.Loaded && tagFeedItem.postList.items.firstOrNull {
it.postId == postItemToUpdate.postId && it.blogId == postItemToUpdate.blogId
} != null
}

private fun likePostRemote(postItem: TagsFeedPostItem, isPostLikedUpdated: Boolean) {
launch {
Expand Down Expand Up @@ -317,8 +332,50 @@ class ReaderTagsFeedViewModel @Inject constructor(
}
}

private fun onPostMoreMenuClick() {
// TODO
private fun onPostMoreMenuClick(postItem: TagsFeedPostItem) {
launch {
findPost(postItem.postId, postItem.blogId)?.let { post ->
val items = readerPostMoreButtonUiStateBuilder.buildMoreMenuItems(
post = post,
includeBookmark = true,
onButtonClicked = ::onMoreMenuButtonClicked,
)
val photonWidth: Int = (displayUtilsWrapper.getDisplayPixelWidth() * PHOTON_WIDTH_QUALITY_RATION).toInt()
val photonHeight: Int = (photonWidth * FEATURED_IMAGE_HEIGHT_WIDTH_RATION).toInt()
_openMoreMenuEvents.postValue(
MoreMenuUiState(
readerCardUiState = readerPostUiStateBuilder.mapPostToNewUiState(
source = ReaderTracker.SOURCE_TAGS_FEED,
post = post,
photonWidth = photonWidth,
photonHeight = photonHeight,
postListType = ReaderTypes.ReaderPostListType.TAGS_FEED,
onButtonClicked = {_, _, _ -> },
onItemClicked = {_, _ -> },
onItemRendered = {},
onMoreButtonClicked = {},
onMoreDismissed = {},
onVideoOverlayClicked = {_, _ ->},
onPostHeaderViewClicked = {_, _ -> },
),
readerPostCardActions = items,
)
)
}
}
}

private fun onMoreMenuButtonClicked(postId: Long, blogId: Long, type: ReaderPostCardActionType) {
launch {
findPost(postId, blogId)?.let {
readerPostCardActionsHandler.onAction(
it,
type,
isBookmarkList = false,
source = ReaderTracker.SOURCE_DISCOVER
)
}
}
}

private fun findPost(postId: Long, blogId: Long): ReaderPost? {
Expand Down Expand Up @@ -368,4 +425,9 @@ class ReaderTagsFeedViewModel @Inject constructor(

data object NoContent : ErrorType
}

data class MoreMenuUiState(
val readerCardUiState: ReaderCardUiState.ReaderPostNewUiState,
val readerPostCardActions: List<ReaderPostCardAction>,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ data class TagsFeedPostItem(
val onSiteClick: (TagsFeedPostItem) -> Unit,
val onPostCardClick: (TagsFeedPostItem) -> Unit,
val onPostLikeClick: (TagsFeedPostItem) -> Unit,
val onPostMoreMenuClick: () -> Unit,
val onPostMoreMenuClick: (TagsFeedPostItem) -> Unit,
)

@Preview
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.wordpress.android.ui.reader.views.compose.tagsfeed

import android.annotation.SuppressLint
import android.content.res.Configuration
import androidx.compose.foundation.background
import android.widget.Button
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.isSystemInDarkTheme
Expand All @@ -17,31 +18,26 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import coil.compose.AsyncImage
import coil.request.ImageRequest
import org.wordpress.android.R
Expand All @@ -50,6 +46,7 @@ import org.wordpress.android.ui.compose.theme.AppColor
import org.wordpress.android.ui.compose.theme.AppTheme
import org.wordpress.android.ui.compose.unit.Margin

@SuppressLint("ResourceType")
@Composable
fun ReaderTagsFeedPostListItem(
item: TagsFeedPostItem,
Expand Down Expand Up @@ -224,27 +221,36 @@ fun ReaderTagsFeedPostListItem(
}
Spacer(Modifier.weight(1f))
// More menu ("…")
Column(
horizontalAlignment = Alignment.End,
) {
var isMenuVisible by remember { mutableStateOf(false) }
IconButton(
modifier = Modifier.size(24.dp),
onClick = {
onPostMoreMenuClick()
isMenuVisible = !isMenuVisible
},
) {
Icon(
painter = painterResource(R.drawable.ic_more_ellipsis_horizontal_squares),
contentDescription = stringResource(R.string.show_more_desc),
tint = secondaryElementColor,
)
AndroidView(
factory = { context ->
Button(context).apply {
text = "..."
tag = "${item.blogId}${item.postId}"
setOnClickListener { onPostMoreMenuClick(item) }
}
}
ReaderTagsFeedMoreMenu(
expanded = isMenuVisible,
)
}
)
// Column(
// horizontalAlignment = Alignment.End,
// ) {
// var isMenuVisible by remember { mutableStateOf(false) }
// IconButton(
// modifier = Modifier.size(24.dp),
// onClick = {
// onPostMoreMenuClick()
// isMenuVisible = !isMenuVisible
// },
// ) {
// Icon(
// painter = painterResource(R.drawable.ic_more_ellipsis_horizontal_squares),
// contentDescription = stringResource(R.string.show_more_desc),
// tint = secondaryElementColor,
// )
// }
// ReaderTagsFeedMoreMenu(
// expanded = isMenuVisible,
// )
// }
}
}
}
Expand Down

0 comments on commit 91bc858

Please sign in to comment.