Skip to content

Commit

Permalink
Merge branch 'feature/reader-ia' into issue/19906-reader-ia-implement…
Browse files Browse the repository at this point in the history
…-analytics-events-dropdown-menu
  • Loading branch information
RenanLukas committed Jan 13, 2024
2 parents 09aa198 + cd6fb60 commit b581541
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

public class ReaderConstants {
// max # posts to request when updating posts
public static final int READER_MAX_POSTS_TO_REQUEST = 20;
public static final int READER_MAX_POSTS_TO_REQUEST = 7;

// max # results to request when searching posts & sites
public static final int READER_MAX_SEARCH_RESULTS_TO_REQUEST = 20;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,8 @@ class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider,
onMenuItemClick = viewModel::onTopBarMenuItemClick,
onFilterClick = ::tryOpenFilterList,
onClearFilterClick = ::clearFilter,
onSearchClick = {}
isSearchVisible = state.isSearchActionVisible,
onSearchClick = viewModel::onSearchActionClicked,
)
}
}
Expand Down Expand Up @@ -384,6 +385,6 @@ class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider,

private fun clearFilter() {
val viewModel = getSubFilterViewModel() ?: return
viewModel.setDefaultSubfilter()
viewModel.setDefaultSubfilter(isClearingFilter = true)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -638,7 +638,6 @@ private void initSubFilterViewModel(@Nullable Bundle savedInstanceState) {
visibleState.getCategories(),
mUiHelpers.getTextOfUiString(requireContext(), visibleState.getTitle())
);
mReaderTracker.track(Stat.READER_FILTER_SHEET_DISPLAYED);
bottomSheet.show(getChildFragmentManager(), SUBFILTER_BOTTOM_SHEET_TAG);
} else if (!uiState.isVisible() && bottomSheet != null) {
bottomSheet.dismiss();
Expand Down Expand Up @@ -792,7 +791,7 @@ private void resumeFollowedTag() {
mSubFilterViewModel.setSubfilterFromTag(newTag);
} else if (isFollowingScreen() && !ReaderTagTable.tagExists(getCurrentTag())) {
// user just removed a tag which was selected in the subfilter
mSubFilterViewModel.setDefaultSubfilter();
mSubFilterViewModel.setDefaultSubfilter(false);
} else {
// otherwise, refresh posts to make sure any changes are reflected and auto-update
// posts in the current tag if it's time
Expand Down Expand Up @@ -828,7 +827,7 @@ private void resumeFollowedSite(Site currentSite) {
refreshPosts();
} else {
if (mIsFilterableScreen) {
mSubFilterViewModel.setDefaultSubfilter();
mSubFilterViewModel.setDefaultSubfilter(false);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class ReaderDiscoverLogic @Inject constructor(
insertBlogsIntoDb(cards.filterIsInstance<ReaderRecommendedBlogsCard>().map { it.blogs }.flatten())

// Simplify the json. The simplified version is used in the upper layers to load the data from the db.
val simplifiedCardsJson = createSimplifiedJson(fullCardsJson)
val simplifiedCardsJson = createSimplifiedJson(fullCardsJson, taskType)
insertCardsJsonIntoDb(simplifiedCardsJson)

val nextPageHandle = parseDiscoverCardsJsonUseCase.parseNextPageHandle(json)
Expand Down Expand Up @@ -198,7 +198,7 @@ class ReaderDiscoverLogic @Inject constructor(
* as it's already stored in the db.
*/
@Suppress("NestedBlockDepth")
private fun createSimplifiedJson(cardsJsonArray: JSONArray): JSONArray {
private fun createSimplifiedJson(cardsJsonArray: JSONArray, discoverTasks: DiscoverTasks): JSONArray {
var index = 0
val simplifiedJson = JSONArray()
for (i in 0 until cardsJsonArray.length()) {
Expand All @@ -212,6 +212,10 @@ class ReaderDiscoverLogic @Inject constructor(
}
}
JSON_CARD_INTERESTS_YOU_MAY_LIKE -> {
// We should not have an interests/tags card as the first element on Discover feed.
if (i == 0 && discoverTasks == REQUEST_FIRST_PAGE) {
continue
}
simplifiedJson.put(index++, cardJson)
}
JSON_CARD_POST -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,13 +193,14 @@ class SubFilterViewModel @Inject constructor(
)
}

fun setDefaultSubfilter() {
fun setDefaultSubfilter(isClearingFilter: Boolean) {
readerTracker.track(Stat.READER_FILTER_SHEET_CLEARED)
updateSubfilter(
SiteAll(
filter = SiteAll(
onClickAction = ::onSubfilterClicked,
isSelected = true
)
isSelected = true,
isClearingFilter = isClearingFilter,
),
)
}

Expand All @@ -213,6 +214,11 @@ class SubFilterViewModel @Inject constructor(
listOf(category) // TODO thomashortadev this should accept only a single category
)
)
val source = when(category) {
SubfilterCategory.SITES -> "blogs"
SubfilterCategory.TAGS -> "tags"
}
readerTracker.track(Stat.READER_FILTER_SHEET_DISPLAYED, source)
}

fun updateTagsAndSites() {
Expand Down Expand Up @@ -286,7 +292,10 @@ class SubFilterViewModel @Inject constructor(
}

fun onSubfilterSelected(subfilterListItem: SubfilterListItem) {
readerTracker.track(Stat.READER_FILTER_SHEET_ITEM_SELECTED)
// We should not track subfilter selected if we're clearing a filter that is currently applied.
if (!subfilterListItem.isClearingFilter) {
readerTracker.track(Stat.READER_FILTER_SHEET_ITEM_SELECTED)
}
changeSubfilter(subfilterListItem, true, mTagFragmentStartedWith)
}

Expand Down Expand Up @@ -340,7 +349,7 @@ class SubFilterViewModel @Inject constructor(
)
)

setDefaultSubfilter()
setDefaultSubfilter(false)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import org.wordpress.android.ui.utils.UiString.UiStringText

sealed class SubfilterListItem(val type: ItemType, val isTrackedItem: Boolean = false) {
open var isSelected: Boolean = false
open var isClearingFilter: Boolean = false
open val onClickAction: ((filter: SubfilterListItem) -> Unit)? = null
open val label: UiString? = null

Expand Down Expand Up @@ -52,6 +53,7 @@ sealed class SubfilterListItem(val type: ItemType, val isTrackedItem: Boolean =
@Suppress("DataClassShouldBeImmutable")
data class SiteAll(
override var isSelected: Boolean = false,
override var isClearingFilter: Boolean = false,
override val onClickAction: (filter: SubfilterListItem) -> Unit
) : SubfilterListItem(SITE_ALL) {
override val label: UiString = UiStringRes(R.string.reader_filter_cta)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import org.wordpress.android.ui.stats.refresh.utils.StatsUtils
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.config.SeenUnseenWithCounterFeatureConfig
import org.wordpress.android.util.extensions.getSerializableCompat
import org.wordpress.android.util.image.ImageManager
import org.wordpress.android.widgets.WPTextView
import java.lang.ref.WeakReference
import javax.inject.Inject
Expand All @@ -47,6 +48,9 @@ class SubfilterPageFragment : Fragment() {
@Inject
lateinit var uiHelpers: UiHelpers

@Inject
lateinit var imageManager: ImageManager

@Inject
lateinit var seenUnseenWithCounterFeatureConfig: SeenUnseenWithCounterFeatureConfig

Expand Down Expand Up @@ -89,7 +93,8 @@ class SubfilterPageFragment : Fragment() {

recyclerView = view.findViewById(R.id.content_recycler_view)
recyclerView.layoutManager = LinearLayoutManager(requireActivity())
recyclerView.adapter = SubfilterListAdapter(uiHelpers, statsUtils, seenUnseenWithCounterFeatureConfig)
recyclerView.adapter =
SubfilterListAdapter(uiHelpers, statsUtils, imageManager, seenUnseenWithCounterFeatureConfig)

emptyStateContainer = view.findViewById(R.id.empty_state_container)
title = emptyStateContainer.findViewById(R.id.title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ import org.wordpress.android.ui.reader.subfilter.viewholders.TagViewHolder
import org.wordpress.android.ui.stats.refresh.utils.StatsUtils
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.config.SeenUnseenWithCounterFeatureConfig
import org.wordpress.android.util.image.ImageManager

class SubfilterListAdapter(
val uiHelpers: UiHelpers,
val statsUtils: StatsUtils,
val imageManager: ImageManager,
val seenUnseenWithCounterFeatureConfig: SeenUnseenWithCounterFeatureConfig
) : Adapter<SubfilterListItemViewHolder>() {
private var items: List<SubfilterListItem> = listOf()
Expand All @@ -52,6 +54,7 @@ class SubfilterListAdapter(
is SiteViewHolder -> holder.bind(
item as Site,
uiHelpers,
imageManager,
statsUtils,
seenUnseenWithCounterFeatureConfig.isEnabled()
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,34 @@ package org.wordpress.android.ui.reader.subfilter.viewholders

import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.core.view.isVisible
import org.wordpress.android.R
import org.wordpress.android.models.ReaderBlog
import org.wordpress.android.ui.reader.subfilter.SubfilterListItem.Site
import org.wordpress.android.ui.stats.refresh.utils.ONE_THOUSAND
import org.wordpress.android.ui.stats.refresh.utils.StatsUtils
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.UrlUtils
import org.wordpress.android.util.image.ImageManager
import org.wordpress.android.util.image.ImageType

class SiteViewHolder(
parent: ViewGroup
) : SubfilterListItemViewHolder(parent, R.layout.subfilter_list_item) {
private val itemTitle = itemView.findViewById<TextView>(R.id.item_title)
private val itemUrl = itemView.findViewById<TextView>(R.id.item_url)
private val itemUnseenCount = itemView.findViewById<TextView>(R.id.unseen_count)
private val itemAvatar = itemView.findViewById<ImageView>(R.id.item_avatar)

fun bind(site: Site, uiHelpers: UiHelpers, statsUtils: StatsUtils, showUnreadpostsCount: Boolean) {
fun bind(
site: Site,
uiHelpers: UiHelpers,
imageManager: ImageManager,
statsUtils: StatsUtils,
showUnreadpostsCount: Boolean
) {
super.bind(site, uiHelpers)
this.itemTitle.text = uiHelpers.getTextOfUiString(parent.context, site.label)
this.itemUrl.visibility = View.VISIBLE
Expand All @@ -36,5 +48,21 @@ class SiteViewHolder(
} else {
this.itemUnseenCount.visibility = View.GONE
}

updateSiteAvatar(blog, imageManager)
}

private fun updateSiteAvatar(blog: ReaderBlog, imageManager: ImageManager) {
itemAvatar.isVisible = true
if (blog.hasImageUrl()) {
imageManager.loadIntoCircle(
itemAvatar,
ImageType.BLAVATAR_CIRCULAR,
blog.imageUrl,
)
} else {
imageManager.cancelRequestAndClearImageView(itemAvatar)
itemAvatar.setImageResource(R.drawable.bg_oval_placeholder_globe_no_border_24dp)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,7 @@ class ReaderViewModel @Inject constructor(
selectedItem = selectedItem,
filterUiState = filterUiState,
onDropdownMenuClick = ::onDropdownMenuClick,
isSearchActionVisible = isSearchSupported(),
)
)
}
Expand Down Expand Up @@ -507,6 +508,7 @@ class ReaderViewModel @Inject constructor(
val selectedItem: MenuElementData.Item.Single,
val filterUiState: FilterUiState? = null,
val onDropdownMenuClick: () -> Unit,
val isSearchActionVisible: Boolean = false,
) {
data class FilterUiState(
val blogsFilterCount: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ fun ReaderTopAppBar(
onMenuItemClick: (MenuElementData.Item.Single) -> Unit,
onFilterClick: (ReaderFilterType) -> Unit,
onClearFilterClick: () -> Unit,
onSearchClick: () -> Unit,
isSearchVisible: Boolean,
onSearchClick: () -> Unit = {},
) {
var selectedItem by remember { mutableStateOf(topBarUiState.selectedItem) }
var isFilterShown by remember { mutableStateOf(topBarUiState.filterUiState != null) }
Expand Down Expand Up @@ -125,17 +126,19 @@ fun ReaderTopAppBar(
}
}
Spacer(Modifier.width(Margin.ExtraSmall.value))
IconButton(
modifier = Modifier.align(Alignment.CenterVertically),
onClick = { onSearchClick() }
) {
Icon(
painter = painterResource(R.drawable.ic_magnifying_glass_16dp),
contentDescription = stringResource(
R.string.reader_search_content_description
),
tint = MaterialTheme.colors.onSurface,
)
if (isSearchVisible) {
IconButton(
modifier = Modifier.align(Alignment.CenterVertically),
onClick = { onSearchClick() }
) {
Icon(
painter = painterResource(R.drawable.ic_magnifying_glass_16dp),
contentDescription = stringResource(
R.string.reader_search_content_description
),
tint = MaterialTheme.colors.onSurface,
)
}
}
}
}
Expand Down Expand Up @@ -227,6 +230,7 @@ fun ReaderTopAppBarPreview() {
},
onFilterClick = {},
onClearFilterClick = {},
isSearchVisible = true,
onSearchClick = {},
)
}
Expand Down
20 changes: 18 additions & 2 deletions WordPress/src/main/res/layout/subfilter_list_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,29 @@
style="@style/SubfilterSiteTagItem"
android:layout_width="match_parent">

<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/item_avatar"
style="@style/ReaderImageView.Avatar.OvalSurfaceBackground"
android:visibility="gone"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constraintTop_toTopOf="@id/item_title"
app:layout_constraintBottom_toBottomOf="@id/item_url"
app:layout_constraintStart_toStartOf="parent"
tools:src="@drawable/bg_oval_placeholder_globe_no_border_24dp"
tools:visibility="visible" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/item_title"
style="@style/SiteTagFilteredTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_large"
app:layout_constraintEnd_toStartOf="@+id/unseen_count"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintStart_toEndOf="@id/item_avatar"
app:layout_constraintBottom_toTopOf="@+id/item_url"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginStart="0dp"
app:layout_goneMarginBottom="@dimen/margin_large"
app:layout_goneMarginEnd="0dp"
tools:text="Unknown" />
Expand All @@ -23,11 +37,13 @@
style="@style/SiteTagFilteredUrl"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/margin_large"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/unseen_count"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintStart_toEndOf="@id/item_avatar"
app:layout_constraintTop_toBottomOf="@+id/item_title"
android:visibility="visible"
app:layout_goneMarginStart="0dp"
app:layout_goneMarginEnd="0dp"
tools:text="www.unknown.com" />

Expand Down
Loading

0 comments on commit b581541

Please sign in to comment.