Skip to content

Commit

Permalink
Merge pull request #20130 from wordpress-mobile/issue/20109-reader-ia…
Browse files Browse the repository at this point in the history
…-quick-start

[Reader IA] Simplify Reader Quick Start flow for new UX
  • Loading branch information
Thomas Horta authored Feb 6, 2024
2 parents eb28864 + 1828b60 commit 818bd93
Show file tree
Hide file tree
Showing 9 changed files with 48 additions and 307 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ enum class QuickStartMySitePrompts constructor(
R.id.root_view_main,
R.id.bottom_nav_reader_button,
R.string.quick_start_dialog_follow_sites_message_short_reader,
R.drawable.ic_reader_white_24dp
R.drawable.ic_reader_selected
),
UPLOAD_SITE_ICON(
QuickStartStore.QUICK_START_UPLOAD_SITE_ICON_LABEL,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
package org.wordpress.android.ui.reader

import android.os.Bundle
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.core.view.MenuProvider
import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
Expand Down Expand Up @@ -48,12 +44,11 @@ import org.wordpress.android.util.SnackbarItem.Action
import org.wordpress.android.util.SnackbarItem.Info
import org.wordpress.android.util.SnackbarSequencer
import org.wordpress.android.viewmodel.observeEvent
import org.wordpress.android.widgets.QuickStartFocusPoint
import java.util.EnumSet
import javax.inject.Inject

@AndroidEntryPoint
class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider, ScrollableViewInitializedListener {
class ReaderFragment : Fragment(R.layout.reader_fragment_layout), ScrollableViewInitializedListener {
@Inject
lateinit var viewModelFactory: ViewModelProvider.Factory

Expand All @@ -70,14 +65,9 @@ class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider,
lateinit var snackbarSequencer: SnackbarSequencer
private lateinit var viewModel: ReaderViewModel

private var searchMenuItem: MenuItem? = null
private var settingsMenuItem: MenuItem? = null
private var settingsMenuItemFocusPoint: QuickStartFocusPoint? = null

private var binding: ReaderFragmentLayoutBinding? = null

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
requireActivity().addMenuProvider(this, viewLifecycleOwner)
binding = ReaderFragmentLayoutBinding.bind(view).apply {
initTopAppBar()
initViewModel(savedInstanceState)
Expand All @@ -86,9 +76,6 @@ class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider,

override fun onDestroyView() {
super.onDestroyView()
searchMenuItem = null
settingsMenuItem = null
settingsMenuItemFocusPoint = null
binding = null
}

Expand All @@ -102,36 +89,6 @@ class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider,
activity?.let { viewModel.onScreenInBackground(it.isChangingConfigurations) }
}

override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {
menuInflater.inflate(R.menu.reader_home, menu)
menu.findItem(R.id.menu_search).apply {
searchMenuItem = this
this.isVisible = viewModel.uiState.value?.searchMenuItemUiState?.isVisible ?: false
}
menu.findItem(R.id.menu_settings).apply {
settingsMenuItem = this
settingsMenuItemFocusPoint = this.actionView?.findViewById(R.id.menu_quick_start_focus_point)
this.isVisible = viewModel.uiState.value?.settingsMenuItemUiState?.isVisible ?: false
settingsMenuItemFocusPoint?.isVisible =
viewModel.uiState.value?.settingsMenuItemUiState?.showQuickStartFocusPoint ?: false
this.actionView?.setOnClickListener { viewModel.onSettingsActionClicked() }
}
}

override fun onMenuItemSelected(menuItem: MenuItem) = when (menuItem.itemId) {
R.id.menu_search -> {
viewModel.onSearchActionClicked()
true
}

R.id.menu_settings -> {
viewModel.onSettingsActionClicked()
true
}

else -> false
}

private fun ReaderFragmentLayoutBinding.initTopAppBar() {
readerTopBarComposeView.apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
Expand Down Expand Up @@ -171,10 +128,6 @@ class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider,
ReaderActivityLauncher.showReaderSearch(context)
}

viewModel.showSettings.observeEvent(viewLifecycleOwner) {
ReaderActivityLauncher.showReaderSubs(context)
}

viewModel.showReaderInterests.observeEvent(viewLifecycleOwner) {
showReaderInterests()
}
Expand Down Expand Up @@ -225,12 +178,6 @@ class ReaderFragment : Fragment(R.layout.reader_fragment_layout), MenuProvider,
initContentContainer(uiState)
}
}
// TODO As part of Reader IA changes this view is going to be replaced
// uiHelpers.updateVisibility(tabLayout, uiState.tabLayoutVisible)
searchMenuItem?.isVisible = uiState.searchMenuItemUiState.isVisible
settingsMenuItem?.isVisible = uiState.settingsMenuItemUiState.isVisible
settingsMenuItemFocusPoint?.isVisible =
viewModel.uiState.value?.settingsMenuItemUiState?.showQuickStartFocusPoint ?: false
}

private fun initContentContainer(uiState: ContentUiState) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,6 @@ class ReaderInterestsViewModel @Inject constructor(
)
)
)

parentViewModel?.completeQuickStartFollowSiteTaskIfNeeded()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,13 @@ import org.wordpress.android.ui.reader.usecases.LoadReaderTabsUseCase
import org.wordpress.android.ui.reader.utils.DateProvider
import org.wordpress.android.ui.reader.utils.ReaderTopBarMenuHelper
import org.wordpress.android.ui.reader.viewmodels.ReaderViewModel.ReaderUiState.ContentUiState
import org.wordpress.android.ui.reader.viewmodels.ReaderViewModel.ReaderUiState.ContentUiState.MenuItemUiState
import org.wordpress.android.ui.reader.viewmodels.ReaderViewModel.ReaderUiState.ContentUiState.TabUiState
import org.wordpress.android.ui.reader.views.compose.filter.ReaderFilterSelectedItem
import org.wordpress.android.ui.reader.views.compose.filter.ReaderFilterType
import org.wordpress.android.ui.utils.UiString
import org.wordpress.android.ui.utils.UiString.UiStringText
import org.wordpress.android.util.JetpackBrandingUtils
import org.wordpress.android.util.QuickStartUtils
import org.wordpress.android.util.SnackbarSequencer
import org.wordpress.android.util.distinct
import org.wordpress.android.viewmodel.Event
Expand Down Expand Up @@ -94,9 +94,6 @@ class ReaderViewModel @Inject constructor(
private val _showSearch = MutableLiveData<Event<Unit>>()
val showSearch: LiveData<Event<Unit>> = _showSearch

private val _showSettings = MutableLiveData<Event<Unit>>()
val showSettings: LiveData<Event<Unit>> = _showSettings

private val _showReaderInterests = MutableLiveData<Event<Unit>>()
val showReaderInterests: LiveData<Event<Unit>> = _showReaderInterests

Expand Down Expand Up @@ -138,20 +135,13 @@ class ReaderViewModel @Inject constructor(

private fun loadTabs(savedInstanceState: Bundle? = null) {
launch {
val currentContentUiState = _uiState.value as? ContentUiState
val tagList = loadReaderTabsUseCase.loadTabs()
if (tagList.isNotEmpty() && readerTagsList != tagList) {
updateReaderTagsList(tagList)
updateTopBarUiState(savedInstanceState)
_uiState.value = ContentUiState(
tabUiStates = tagList.map { TabUiState(label = UiStringText(it.label)) },
selectedReaderTag = selectedReaderTag(),
searchMenuItemUiState = MenuItemUiState(isVisible = isSearchSupported()),
settingsMenuItemUiState = MenuItemUiState(
isVisible = isSettingsSupported(),
showQuickStartFocusPoint =
currentContentUiState?.settingsMenuItemUiState?.showQuickStartFocusPoint ?: false
)
)
if (!initialized) {
initialized = true
Expand Down Expand Up @@ -221,16 +211,6 @@ class ReaderViewModel @Inject constructor(
}
}

@Suppress("UseCheckOrError")
fun onSettingsActionClicked() {
if (isSettingsSupported()) {
completeQuickStartFollowSiteTaskIfNeeded()
_showSettings.value = Event(Unit)
} else if (BuildConfig.DEBUG) {
throw IllegalStateException("Settings should be hidden when isSettingsSupported returns false.")
}
}

@Suppress("unused", "UNUSED_PARAMETER")
@Subscribe(threadMode = MAIN)
fun onTagsUpdated(event: ReaderEvents.FollowedTagsChanged) {
Expand All @@ -253,7 +233,6 @@ class ReaderViewModel @Inject constructor(
readerTracker.stop(MAIN_READER)
wasPaused = true
if (!isChangingConfigurations) {
hideQuickStartFocusPointIfNeeded()
dismissQuickStartSnackbarIfNeeded()
if (quickStartRepository.isPendingTask(getFollowSiteTask())) {
quickStartRepository.clearPendingTask()
Expand Down Expand Up @@ -281,31 +260,12 @@ class ReaderViewModel @Inject constructor(
}

fun onQuickStartEventReceived(event: QuickStartEvent) {
if (event.task == getFollowSiteTask()) checkAndStartQuickStartFollowSiteTaskNextStep()
if (event.task == getFollowSiteTask()) startQuickStartFollowSiteTask()
}

private fun checkAndStartQuickStartFollowSiteTaskNextStep() {
val isDiscover = appPrefsWrapper.getReaderTag()?.isDiscover == true
if (isDiscover) {
startQuickStartFollowSiteTaskDiscoverTabStep()
} else {
autoSwitchToDiscoverTab()
}
}

private fun autoSwitchToDiscoverTab() {
launch {
if (!initialized) delay(QUICK_START_DISCOVER_TAB_STEP_DELAY)
readerTagsList.find { it.isDiscover }?.let {
updateSelectedContent(it)
}
startQuickStartFollowSiteTaskDiscoverTabStep()
}
}

private fun startQuickStartFollowSiteTaskDiscoverTabStep() {
private fun startQuickStartFollowSiteTask() {
val shortMessagePrompt = if (isSettingsSupported()) {
R.string.quick_start_dialog_follow_sites_message_short_discover_and_settings
R.string.quick_start_dialog_follow_sites_message_short_discover_and_subscriptions
} else {
R.string.quick_start_dialog_follow_sites_message_short_discover
}
Expand All @@ -314,16 +274,15 @@ class ReaderViewModel @Inject constructor(
QuickStartReaderPrompt(
getFollowSiteTask(),
shortMessagePrompt,
R.drawable.ic_cog_white_24dp
QuickStartUtils.ICON_NOT_SET,
)
)
updateContentUiState(showQuickStartFocusPoint = isSettingsSupported())
completeQuickStartFollowSiteTaskIfNeeded()
}

fun completeQuickStartFollowSiteTaskIfNeeded() {
private fun completeQuickStartFollowSiteTaskIfNeeded() {
if (quickStartRepository.isPendingTask(getFollowSiteTask())) {
selectedSiteRepository.getSelectedSite()?.let {
hideQuickStartFocusPointIfNeeded()
quickStartRepository.completeTask(getFollowSiteTask())
}
}
Expand All @@ -334,30 +293,9 @@ class ReaderViewModel @Inject constructor(
isQuickStartPromptShown = false
}

private fun hideQuickStartFocusPointIfNeeded() {
val currentUiState = _uiState.value as? ContentUiState
if (currentUiState?.settingsMenuItemUiState?.showQuickStartFocusPoint == true) {
updateContentUiState(showQuickStartFocusPoint = false)
}
}

private fun getFollowSiteTask() =
quickStartRepository.quickStartType.getTaskFromString(QuickStartStore.QUICK_START_FOLLOW_SITE_LABEL)

private fun updateContentUiState(
showQuickStartFocusPoint: Boolean
) {
val currentUiState = _uiState.value as? ContentUiState
currentUiState?.let {
_uiState.value = currentUiState.copy(
settingsMenuItemUiState = it.settingsMenuItemUiState.copy(
isVisible = isSettingsSupported(),
showQuickStartFocusPoint = showQuickStartFocusPoint
),
)
}
}

private fun selectedReaderTag(): ReaderTag? =
_topBarUiState.value?.let {
readerTagsList[readerTopBarMenuHelper.getReaderTagIndexFromMenuItem(it.selectedItem)]
Expand Down Expand Up @@ -561,30 +499,19 @@ class ReaderViewModel @Inject constructor(
}

sealed class ReaderUiState(
open val searchMenuItemUiState: MenuItemUiState,
open val settingsMenuItemUiState: MenuItemUiState,
val appBarExpanded: Boolean = false,
val tabLayoutVisible: Boolean = false
) {
data class ContentUiState(
val tabUiStates: List<TabUiState>,
val selectedReaderTag: ReaderTag?,
override val searchMenuItemUiState: MenuItemUiState,
override val settingsMenuItemUiState: MenuItemUiState,
) : ReaderUiState(
searchMenuItemUiState = searchMenuItemUiState,
settingsMenuItemUiState = settingsMenuItemUiState,
appBarExpanded = true,
tabLayoutVisible = true
) {
data class TabUiState(
val label: UiString
)

data class MenuItemUiState(
val isVisible: Boolean,
val showQuickStartFocusPoint: Boolean = false
)
}
}

Expand All @@ -596,7 +523,6 @@ class ReaderViewModel @Inject constructor(
)

companion object {
private const val QUICK_START_DISCOVER_TAB_STEP_DELAY = 2000L
private const val QUICK_START_PROMPT_DURATION = 5000
private const val FILTER_UPDATE_DELAY = 50L

Expand Down

This file was deleted.

17 changes: 0 additions & 17 deletions WordPress/src/main/res/menu/reader_home.xml

This file was deleted.

2 changes: 1 addition & 1 deletion WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3287,7 +3287,7 @@
<string name="quick_start_dialog_enable_sharing_title" tools:ignore="UnusedResources">Enable post sharing</string>
<string name="quick_start_dialog_follow_sites_message" translatable="false">@string/quick_start_list_follow_site_subtitle</string>
<string name="quick_start_dialog_follow_sites_message_short_reader" tools:ignore="UnusedResources">Select %1$s Reader %2$s to find other sites.</string>
<string name="quick_start_dialog_follow_sites_message_short_discover_and_settings">Use &lt;b&gt; Discover &lt;/b&gt; to find sites and tags. Try selecting %1$s Settings %2$s to add topics you like.</string>
<string name="quick_start_dialog_follow_sites_message_short_discover_and_subscriptions">Use &lt;b&gt;Discover&lt;/b&gt; to find sites and tags. Try selecting &lt;b&gt;Subscriptions&lt;/b&gt; to view subscribed content and manage your subscriptions.</string>
<string name="quick_start_dialog_follow_sites_message_short_discover">Use &lt;b&gt; Discover &lt;/b&gt; to find sites and tags.</string>
<string name="quick_start_dialog_upload_media_message_short_plus" tools:ignore="UnusedResources">Select %1$s plus %2$s to upload media. You can add it to your posts/ pages from any device.</string>
<string name="quick_start_dialog_follow_sites_title">Connect with other sites</string>
Expand Down
Loading

0 comments on commit 818bd93

Please sign in to comment.