Skip to content

Commit

Permalink
Merge pull request #20925 from wordpress-mobile/issue/20908-reader-cr…
Browse files Browse the repository at this point in the history
…eate-post-fab-release

[Reader] Show "Create Post" FAB in Reader
  • Loading branch information
Thomas Horta authored Jun 3, 2024
2 parents 4f6014a + 096ad6e commit 7da0f0a
Show file tree
Hide file tree
Showing 12 changed files with 862 additions and 153 deletions.
1 change: 1 addition & 0 deletions WordPress/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ android {
buildConfigField "boolean", "READER_TAGS_FEED", "false"
buildConfigField "boolean", "READER_ANNOUNCEMENT_CARD", "false"
buildConfigField "boolean", "VOICE_TO_CONTENT", "false"
buildConfigField "boolean", "READER_FLOATING_BUTTON", "false"

// Override these constants in jetpack product flavor to enable/ disable features
buildConfigField "boolean", "ENABLE_SITE_CREATION", "true"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,14 +760,17 @@ private void initViewModel() {
.show(getSupportFragmentManager(), FeatureAnnouncementDialogFragment.TAG);
});

mFloatingActionButton.setOnClickListener(v -> mViewModel.onFabClicked(getSelectedSite()));
mFloatingActionButton.setOnClickListener(v -> {
PageType selectedPage = getSelectedPage();
if (selectedPage != null) mViewModel.onFabClicked(getSelectedSite(), selectedPage);
});

mFloatingActionButton.setOnLongClickListener(v -> {
if (v.isHapticFeedbackEnabled()) {
v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}

int messageId = mViewModel.getCreateContentMessageId(getSelectedSite());
int messageId = mViewModel.getCreateContentMessageId(getSelectedSite(), getSelectedPage());

Toast.makeText(v.getContext(), messageId, Toast.LENGTH_SHORT).show();
return true;
Expand Down Expand Up @@ -844,7 +847,7 @@ private void initViewModel() {
// initialized with the most restrictive rights case. This is OK and will be frequently checked
// to normalize the UI state whenever mSelectedSite changes.
// It also means that the ViewModel must accept a nullable SiteModel.
mViewModel.start(getSelectedSite());
mViewModel.start(getSelectedSite(), mBottomNav.getCurrentSelectedPage());
}

private void triggerCreatePageFlow(ActionType actionType) {
Expand Down Expand Up @@ -1204,8 +1207,8 @@ protected void onResume() {

mViewModel.onResume(
getSelectedSite(),
mSelectedSiteRepository.hasSelectedSite() && mBottomNav != null
&& mBottomNav.getCurrentSelectedPage() == PageType.MY_SITE
mSelectedSiteRepository.hasSelectedSite(),
getSelectedPage()
);

checkForInAppUpdate();
Expand Down Expand Up @@ -1291,8 +1294,9 @@ public void onPageChanged(int position) {
}

mViewModel.onPageChanged(
mSiteStore.hasSite() && pageType == PageType.MY_SITE,
getSelectedSite()
getSelectedSite(),
mSiteStore.hasSite(),
pageType
);
}

Expand Down Expand Up @@ -2007,4 +2011,9 @@ private void showOpenPageMessageIfNeeded() {
}
}
}

@Nullable
private PageType getSelectedPage() {
return mBottomNav != null ? mBottomNav.getCurrentSelectedPage() : null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.wordpress.android.ui.main.analytics

import org.wordpress.android.analytics.AnalyticsTracker
import org.wordpress.android.ui.main.MainActionListItem
import org.wordpress.android.ui.main.WPMainNavigationView
import org.wordpress.android.ui.mysite.cards.dashboard.bloggingprompts.BloggingPromptAttribution
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
import java.util.Locale
import javax.inject.Inject

class MainCreateSheetTracker @Inject constructor(
private val analyticsTracker: AnalyticsTrackerWrapper,
) {
fun trackActionTapped(page: WPMainNavigationView.PageType, actionType: MainActionListItem.ActionType) {
val stat = when (page) {
WPMainNavigationView.PageType.MY_SITE -> AnalyticsTracker.Stat.MY_SITE_CREATE_SHEET_ACTION_TAPPED
WPMainNavigationView.PageType.READER -> AnalyticsTracker.Stat.READER_CREATE_SHEET_ACTION_TAPPED
else -> return
}
val properties = mapOf("action" to actionType.name.lowercase(Locale.ROOT))
analyticsTracker.track(stat, properties)
}

fun trackAnswerPromptActionTapped(page: WPMainNavigationView.PageType, attribution: BloggingPromptAttribution) {
val properties = mapOf("attribution" to attribution.value).filterValues { it.isNotBlank() }
val stat = when (page) {
WPMainNavigationView.PageType.MY_SITE -> AnalyticsTracker.Stat.MY_SITE_CREATE_SHEET_ANSWER_PROMPT_TAPPED
WPMainNavigationView.PageType.READER -> AnalyticsTracker.Stat.READER_CREATE_SHEET_ANSWER_PROMPT_TAPPED
else -> return
}
analyticsTracker.track(stat, properties)
}

fun trackHelpPromptActionTapped(page: WPMainNavigationView.PageType) {
val stat = when (page) {
WPMainNavigationView.PageType.MY_SITE -> AnalyticsTracker.Stat.MY_SITE_CREATE_SHEET_PROMPT_HELP_TAPPED
WPMainNavigationView.PageType.READER -> AnalyticsTracker.Stat.READER_CREATE_SHEET_PROMPT_HELP_TAPPED
else -> return
}
analyticsTracker.track(stat)
}

fun trackSheetShown(page: WPMainNavigationView.PageType) {
val stat = when (page) {
WPMainNavigationView.PageType.MY_SITE -> AnalyticsTracker.Stat.MY_SITE_CREATE_SHEET_SHOWN
WPMainNavigationView.PageType.READER -> AnalyticsTracker.Stat.READER_CREATE_SHEET_SHOWN
else -> return
}
analyticsTracker.track(stat)
}

fun trackFabShown(page: WPMainNavigationView.PageType) {
val stat = when (page) {
WPMainNavigationView.PageType.MY_SITE -> AnalyticsTracker.Stat.MY_SITE_CREATE_FAB_SHOWN
WPMainNavigationView.PageType.READER -> AnalyticsTracker.Stat.READER_CREATE_FAB_SHOWN
else -> return
}
analyticsTracker.track(stat)
}

fun trackCreateActionsSheetCard(actions: List<MainActionListItem>) {
if (actions.any { it is MainActionListItem.AnswerBloggingPromptAction }) {
analyticsTracker.track(AnalyticsTracker.Stat.BLOGGING_PROMPTS_CREATE_SHEET_CARD_VIEWED)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package org.wordpress.android.ui.main.utils

import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.ui.bloggingprompts.BloggingPromptsSettingsHelper
import org.wordpress.android.ui.main.WPMainNavigationView.PageType
import org.wordpress.android.ui.voicetocontent.VoiceToContentFeatureUtils
import org.wordpress.android.util.BuildConfigWrapper
import org.wordpress.android.util.SiteUtilsWrapper
import org.wordpress.android.util.config.ReaderFloatingButtonFeatureConfig
import javax.inject.Inject

class MainCreateSheetHelper @Inject constructor(
private val voiceToContentFeatureUtils: VoiceToContentFeatureUtils,
private val readerFloatingButtonFeatureConfig: ReaderFloatingButtonFeatureConfig,
private val bloggingPromptsSettingsHelper: BloggingPromptsSettingsHelper,
private val buildConfig: BuildConfigWrapper,
private val siteUtils: SiteUtilsWrapper,
) {
fun shouldShowFabForPage(page: PageType?): Boolean {
val enabledForPage = page == PageType.MY_SITE ||
(page == PageType.READER && readerFloatingButtonFeatureConfig.isEnabled())
return buildConfig.isCreateFabEnabled && enabledForPage
}

@Suppress("FunctionOnlyReturningConstant")
fun canCreatePost(): Boolean = true // for completeness

fun canCreatePage(site: SiteModel?, page: PageType?): Boolean {
return siteUtils.hasFullAccessToContent(site) && page == PageType.MY_SITE
}

fun canCreatePostFromAudio(site: SiteModel?): Boolean {
return voiceToContentFeatureUtils.isVoiceToContentEnabled() && siteUtils.hasFullAccessToContent(site)
}

suspend fun canCreatePromptAnswer(): Boolean = bloggingPromptsSettingsHelper.shouldShowPromptsFeature()
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,5 @@ class SiteUtilsWrapper @Inject constructor(private val appContext: Context) {
fun getSiteIconUrlOfResourceSize(site: SiteModel, @DimenRes sizeRes: Int): String {
return SiteUtils.getSiteIconUrl(site, appContext.resources.getDimensionPixelSize(sizeRes))
}
fun hasFullAccessToContent(site: SiteModel?): Boolean = SiteUtils.hasFullAccessToContent(site)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.wordpress.android.util.config

import org.wordpress.android.BuildConfig
import org.wordpress.android.annotation.Feature
import javax.inject.Inject

private const val READER_FLOATING_BUTTON_REMOTE_FIELD = "reader_floating_button"

@Feature(READER_FLOATING_BUTTON_REMOTE_FIELD, false)
class ReaderFloatingButtonFeatureConfig @Inject constructor(
appConfig: AppConfig
) : FeatureConfig(
appConfig,
BuildConfig.READER_FLOATING_BUTTON,
READER_FLOATING_BUTTON_REMOTE_FIELD
)
Loading

0 comments on commit 7da0f0a

Please sign in to comment.