Skip to content

Commit

Permalink
Merge pull request wordpress-mobile#20956 from wordpress-mobile/merge…
Browse files Browse the repository at this point in the history
…/25.0-final-into-trunk

Merge 25.0 final into trunk
  • Loading branch information
oguzkocer authored Jun 7, 2024
2 parents e56dcc8 + 6454d7f commit 46381b2
Show file tree
Hide file tree
Showing 114 changed files with 4,358 additions and 3,098 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 @@ -21,7 +21,7 @@ class InAppUpdateAnalyticsTracker @Inject constructor(
}

fun trackAppRestartToCompleteUpdate() {
tracker.track(AnalyticsTracker.Stat.IN_APP_UPDATE_COMPLETED_WITH_APP_RESTART)
tracker.track(AnalyticsTracker.Stat.IN_APP_UPDATE_COMPLETED_WITH_APP_RESTART_BY_USER)
}

private fun createPropertyMap(updateType: Int): Map<String, String> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import com.google.android.play.core.install.model.UpdateAvailability.DEVELOPER_T
import com.google.android.play.core.install.model.UpdateAvailability.UPDATE_AVAILABLE
import com.google.android.play.core.install.model.UpdateAvailability.UPDATE_NOT_AVAILABLE
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.wordpress.android.inappupdate.IInAppUpdateManager.Companion.APP_UPDATE_FLEXIBLE_REQUEST_CODE
import org.wordpress.android.inappupdate.IInAppUpdateManager.Companion.APP_UPDATE_IMMEDIATE_REQUEST_CODE

Expand All @@ -33,6 +37,7 @@ import javax.inject.Singleton
@Suppress("TooManyFunctions")
class InAppUpdateManagerImpl(
@ApplicationContext private val applicationContext: Context,
private val coroutineScope: CoroutineScope,
private val appUpdateManager: AppUpdateManager,
private val remoteConfigWrapper: RemoteConfigWrapper,
private val buildConfigWrapper: BuildConfigWrapper,
Expand All @@ -51,8 +56,16 @@ class InAppUpdateManagerImpl(
}

override fun completeAppUpdate() {
inAppUpdateAnalyticsTracker.trackAppRestartToCompleteUpdate()
appUpdateManager.completeUpdate()
coroutineScope.launch(Dispatchers.Main) {
// Track the app restart to complete update
inAppUpdateAnalyticsTracker.trackAppRestartToCompleteUpdate()

// Delay so the event above can be logged
delay(RESTART_DELAY_IN_MILLIS)

// Complete the update
appUpdateManager.completeUpdate()
}
}

override fun cancelAppUpdate(updateType: Int) {
Expand Down Expand Up @@ -226,5 +239,6 @@ class InAppUpdateManagerImpl(
private const val TAG = "AppUpdateChecker"
private const val PREF_NAME = "in_app_update_prefs"
private const val KEY_LAST_APP_UPDATE_CHECK_VERSION = "last_app_update_check_version"
private const val RESTART_DELAY_IN_MILLIS = 500L
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,17 @@
import org.wordpress.android.viewmodel.helpers.ConnectionStatus;
import org.wordpress.android.viewmodel.helpers.ConnectionStatusLiveData;

import javax.inject.Named;

import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.android.AndroidInjectionModule;
import dagger.hilt.InstallIn;
import dagger.hilt.android.qualifiers.ApplicationContext;
import dagger.hilt.components.SingletonComponent;
import kotlinx.coroutines.CoroutineScope;
import static org.wordpress.android.modules.ThreadModuleKt.APPLICATION_SCOPE;

@InstallIn(SingletonComponent.class)
@Module(includes = AndroidInjectionModule.class)
Expand Down Expand Up @@ -98,6 +102,7 @@ public static AppUpdateManager provideAppUpdateManager(@ApplicationContext Conte
@Provides
public static IInAppUpdateManager provideInAppUpdateManager(
@ApplicationContext Context context,
@Named(APPLICATION_SCOPE) CoroutineScope appScope,
AppUpdateManager appUpdateManager,
RemoteConfigWrapper remoteConfigWrapper,
BuildConfigWrapper buildConfigWrapper,
Expand All @@ -108,6 +113,7 @@ public static IInAppUpdateManager provideInAppUpdateManager(
return inAppUpdatesFeatureConfig.isEnabled()
? new InAppUpdateManagerImpl(
context,
appScope,
appUpdateManager,
remoteConfigWrapper,
buildConfigWrapper,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -752,14 +752,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 @@ -831,7 +834,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 @@ -1177,8 +1180,8 @@ protected void onResume() {

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

if (AppReviewManager.INSTANCE.shouldShowInAppReviewsPrompt()) {
Expand Down Expand Up @@ -1267,8 +1270,9 @@ public void onPageChanged(int position) {
}

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

Expand Down Expand Up @@ -1987,4 +1991,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 @@ -3813,7 +3813,12 @@ class EditPostActivity : LocaleAwareActivity(), EditorFragmentActivity, EditorIm
@Subscribe(threadMode = ThreadMode.MAIN)
fun onPostUploaded(event: OnPostUploaded) {
val post: PostModel? = event.post
if (post != null && post.id == editPostRepository.id) {

// Check if editPostRepository is initialized
val editPostRepositoryInitialized = this::editPostRepository.isInitialized
val editPostId = if (editPostRepositoryInitialized) editPostRepository.getPost()?.id else null

if (post != null && post.id == editPostId) {
if (!isRemotePreviewingFromEditor) {
// We are not remote previewing a post: show snackbar and update post status if needed
val snackbarAttachView = findViewById<View>(R.id.editor_activity)
Expand Down
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 46381b2

Please sign in to comment.