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

[Reader] Show "Create Post" FAB in Reader #20910

Closed
wants to merge 10 commits into from
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,18 @@ private void initViewModel() {
.show(getSupportFragmentManager(), FeatureAnnouncementDialogFragment.TAG);
});

mFloatingActionButton.setOnClickListener(v -> mViewModel.onFabClicked(getSelectedSite()));
mFloatingActionButton.setOnClickListener(v -> {
PageType currentPage = mBottomNav != null ? mBottomNav.getCurrentSelectedPage() : null;
thomashorta marked this conversation as resolved.
Show resolved Hide resolved
if (currentPage != null) mViewModel.onFabClicked(getSelectedSite(), currentPage);
});

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

int messageId = mViewModel.getCreateContentMessageId(getSelectedSite());
PageType currentPage = mBottomNav != null ? mBottomNav.getCurrentSelectedPage() : null;
int messageId = mViewModel.getCreateContentMessageId(getSelectedSite(), currentPage);

Toast.makeText(v.getContext(), messageId, Toast.LENGTH_SHORT).show();
return true;
Expand Down Expand Up @@ -844,7 +848,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 @@ -1202,10 +1206,12 @@ protected void onResume() {
ProfilingUtils.dump();
ProfilingUtils.stop();

PageType currentPage = mBottomNav != null ? mBottomNav.getCurrentSelectedPage() : null;

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

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

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package org.wordpress.android.ui.main.utils

import org.wordpress.android.analytics.AnalyticsTracker.Stat
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.ui.bloggingprompts.BloggingPromptsSettingsHelper
import org.wordpress.android.ui.main.MainActionListItem
import org.wordpress.android.ui.main.WPMainNavigationView.PageType
import org.wordpress.android.ui.mysite.cards.dashboard.bloggingprompts.BloggingPromptAttribution
import org.wordpress.android.ui.voicetocontent.VoiceToContentFeatureUtils
import org.wordpress.android.util.BuildConfigWrapper
import org.wordpress.android.util.SiteUtilsWrapper
import org.wordpress.android.util.analytics.AnalyticsTrackerWrapper
import org.wordpress.android.util.config.ReaderFloatingButtonFeatureConfig
import java.util.Locale
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,
private val analyticsTracker: AnalyticsTrackerWrapper,
) {
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
thomashorta marked this conversation as resolved.
Show resolved Hide resolved

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()

// region Analytics
thomashorta marked this conversation as resolved.
Show resolved Hide resolved
fun trackActionTapped(page: PageType, actionType: MainActionListItem.ActionType) {
val stat = when (page) {
PageType.MY_SITE -> Stat.MY_SITE_CREATE_SHEET_ACTION_TAPPED
PageType.READER -> 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: PageType, attribution: BloggingPromptAttribution) {
val properties = mapOf("attribution" to attribution.value).filterValues { it.isNotBlank() }
val stat = when (page) {
PageType.MY_SITE -> Stat.MY_SITE_CREATE_SHEET_ANSWER_PROMPT_TAPPED
PageType.READER -> Stat.READER_CREATE_SHEET_ANSWER_PROMPT_TAPPED
else -> return
}
analyticsTracker.track(stat, properties)
}

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

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

fun trackFabShown(page: PageType) {
val stat = when (page) {
PageType.MY_SITE -> Stat.MY_SITE_CREATE_FAB_SHOWN
PageType.READER -> Stat.READER_CREATE_FAB_SHOWN
else -> return
}
analyticsTracker.track(stat)
}
// endregion
}
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
Loading