Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.wordpress.android.bloggingreminders.resolver

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.wordpress.android.bloggingreminders.BloggingRemindersSyncAnalyticsTracker
import org.wordpress.android.bloggingreminders.BloggingRemindersSyncAnalyticsTracker.ErrorType
import org.wordpress.android.bloggingreminders.JetpackBloggingRemindersSyncFlag
Expand All @@ -12,85 +11,68 @@ import org.wordpress.android.fluxc.store.SiteStore
import org.wordpress.android.localcontentmigration.LocalContentEntity.BloggingReminders
import org.wordpress.android.localcontentmigration.LocalContentEntityData.BloggingRemindersData
import org.wordpress.android.localcontentmigration.LocalMigrationContentResolver
import org.wordpress.android.localcontentmigration.LocalMigrationResult.Companion.EmptyResult
import org.wordpress.android.localcontentmigration.otherwise
import org.wordpress.android.localcontentmigration.LocalMigrationError.FeatureDisabled.BloggingRemindersSyncDisabled
import org.wordpress.android.localcontentmigration.LocalMigrationError.MigrationAlreadyAttempted.BloggingRemindersSyncAlreadyAttempted
import org.wordpress.android.localcontentmigration.LocalMigrationError.PersistenceError.FailedToSaveBloggingRemindersWithException
import org.wordpress.android.localcontentmigration.LocalMigrationResult.Failure
import org.wordpress.android.localcontentmigration.LocalMigrationResult.Success
import org.wordpress.android.localcontentmigration.orElse
import org.wordpress.android.localcontentmigration.thenWith
import org.wordpress.android.modules.APPLICATION_SCOPE
import org.wordpress.android.ui.bloggingreminders.BloggingRemindersModelMapper
import org.wordpress.android.ui.prefs.AppPrefsWrapper
import org.wordpress.android.workers.reminder.ReminderScheduler
import javax.inject.Inject
import javax.inject.Named

class BloggingRemindersResolver @Inject constructor(
class BloggingRemindersHelper @Inject constructor(
private val jetpackBloggingRemindersSyncFlag: JetpackBloggingRemindersSyncFlag,
private val appPrefsWrapper: AppPrefsWrapper,
private val bloggingRemindersSyncAnalyticsTracker: BloggingRemindersSyncAnalyticsTracker,
private val siteStore: SiteStore,
private val bloggingRemindersStore: BloggingRemindersStore,
@Named(APPLICATION_SCOPE) private val coroutineScope: CoroutineScope,
private val reminderScheduler: ReminderScheduler,
private val bloggingRemindersModelMapper: BloggingRemindersModelMapper,
private val localMigrationContentResolver: LocalMigrationContentResolver,
) {
fun trySyncBloggingReminders(onSuccess: () -> Unit, onFailure: () -> Unit) {
if (!shouldTrySyncBloggingReminders()) {
onFailure()
return
}
fun migrateBloggingReminders() = if (!jetpackBloggingRemindersSyncFlag.isEnabled()) {
Failure(BloggingRemindersSyncDisabled)
} else if (!appPrefsWrapper.getIsFirstTryBloggingRemindersSyncJetpack()) {
Failure(BloggingRemindersSyncAlreadyAttempted)
} else {
bloggingRemindersSyncAnalyticsTracker.trackStart()
appPrefsWrapper.saveIsFirstTryBloggingRemindersSyncJetpack(false)
localMigrationContentResolver.getResultForEntityType<BloggingRemindersData>(BloggingReminders)
.thenWith { (reminders) ->
if (reminders.isNotEmpty()) {
val success = setBloggingReminders(reminders)
if (success) onSuccess() else onFailure()
.orElse {
bloggingRemindersSyncAnalyticsTracker.trackFailed(ErrorType.QueryBloggingRemindersError)
Failure(it)
}
}.thenWith(::setBloggingReminders)

private fun setBloggingReminders(bloggingRemindersData: BloggingRemindersData) = runCatching {
bloggingRemindersData.reminders.count { bloggingReminder ->
siteStore.getSiteByLocalId(bloggingReminder.siteId)?.let { _ ->
if (!isBloggingReminderAlreadySet(bloggingReminder.siteId)) {
updateBloggingReminders(bloggingReminder)
setLocalReminderNotification(bloggingReminder)
true
} else {
bloggingRemindersSyncAnalyticsTracker.trackSuccess(0)
onSuccess()
false
}
EmptyResult
}.otherwise { onFailure() }
} ?: false
}.let { bloggingRemindersSyncAnalyticsTracker.trackSuccess(it) }
Success(bloggingRemindersData)
}.getOrElse { throwable ->
bloggingRemindersSyncAnalyticsTracker.trackFailed(ErrorType.UpdateBloggingRemindersError)
Failure(FailedToSaveBloggingRemindersWithException(throwable))
}

@Suppress("ReturnCount")
private fun shouldTrySyncBloggingReminders(): Boolean {
val isFeatureFlagEnabled = jetpackBloggingRemindersSyncFlag.isEnabled()
if (!isFeatureFlagEnabled) {
return false
}
val isFirstTry = appPrefsWrapper.getIsFirstTryBloggingRemindersSyncJetpack()
if (!isFirstTry) {
return false
}
bloggingRemindersSyncAnalyticsTracker.trackStart()
appPrefsWrapper.saveIsFirstTryBloggingRemindersSyncJetpack(false)
return true
private fun isBloggingReminderAlreadySet(siteLocalId: Int) = runBlocking {
bloggingRemindersStore.bloggingRemindersModel(siteLocalId).first().enabledDays.isNotEmpty()
}

@Suppress("TooGenericExceptionCaught", "SwallowedException")
private fun setBloggingReminders(reminders: List<BloggingRemindersModel>): Boolean {
try {
coroutineScope.launch {
var syncCount = 0
for (bloggingReminder in reminders) {
val site = siteStore.getSiteByLocalId(bloggingReminder.siteId)
if (site != null && !isBloggingReminderAlreadySet(bloggingReminder.siteId)) {
bloggingRemindersStore.updateBloggingReminders(bloggingReminder)
setLocalReminderNotification(bloggingReminder)
syncCount = syncCount.inc()
}
}
bloggingRemindersSyncAnalyticsTracker.trackSuccess(syncCount)
}
return true
} catch (exception: Exception) {
bloggingRemindersSyncAnalyticsTracker.trackFailed(ErrorType.UpdateBloggingRemindersError)
return false
}
private fun updateBloggingReminders(bloggingReminder: BloggingRemindersModel) = runBlocking {
bloggingRemindersStore.updateBloggingReminders(bloggingReminder)
}

private suspend fun isBloggingReminderAlreadySet(siteLocalId: Int) =
bloggingRemindersStore.bloggingRemindersModel(siteLocalId).first().enabledDays.isNotEmpty()

private fun setLocalReminderNotification(bloggingRemindersModel: BloggingRemindersModel) {
val bloggingRemindersUiModel = bloggingRemindersModelMapper.toUiModel(bloggingRemindersModel)
reminderScheduler.schedule(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,22 @@ sealed class LocalMigrationError {
object SharedLoginDisabled : FeatureDisabled()
object UserFlagsDisabled : FeatureDisabled()
object ReaderSavedPostsDisabled : FeatureDisabled()
object BloggingRemindersSyncDisabled : FeatureDisabled()
}

sealed class MigrationAlreadyAttempted : LocalMigrationError() {
object SharedLoginAlreadyAttempted : MigrationAlreadyAttempted()
object UserFlagsAlreadyAttempted : MigrationAlreadyAttempted()
object ReaderSavedPostsAlreadyAttempted : MigrationAlreadyAttempted()
object BloggingRemindersSyncAlreadyAttempted : MigrationAlreadyAttempted()
}

sealed class PersistenceError : LocalMigrationError() {
data class FailedToSaveSites(val throwable: Throwable) : PersistenceError()
object FailedToSaveUserFlags : PersistenceError()
data class FailedToSaveUserFlagsWithException(val throwable: Throwable) : PersistenceError()
object FailedToSaveReaderSavedPosts : PersistenceError()
data class FailedToSaveBloggingRemindersWithException(val throwable: Throwable) : PersistenceError()
sealed class LocalPostsPersistenceError : PersistenceError() {
data class FailedToResetSequenceForPosts(val throwable: Throwable) : LocalPostsPersistenceError()
data class FailedToInsertLocalPost(val post: PostModel) : LocalPostsPersistenceError()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ fun <T : LocalContentEntityData> LocalMigrationResult<LocalContentEntityData, Lo
is Failure -> this
}

fun <E : LocalMigrationError> LocalMigrationResult<LocalContentEntityData, E>.orElse(
handleError: (E) -> LocalMigrationResult<LocalContentEntityData, LocalMigrationError>
fun <T : LocalContentEntityData, E : LocalMigrationError> LocalMigrationResult<T, E>.orElse(
handleError: (E) -> LocalMigrationResult<T, LocalMigrationError>
) = when (this) {
is Success -> this
is Failure -> handleError(this.error)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.wordpress.android.sharedlogin.resolver

import kotlinx.coroutines.flow.MutableStateFlow
import org.wordpress.android.bloggingreminders.resolver.BloggingRemindersHelper
import org.wordpress.android.localcontentmigration.ContentMigrationAnalyticsTracker
import org.wordpress.android.localcontentmigration.ContentMigrationAnalyticsTracker.ErrorType.LocalDraftContent
import org.wordpress.android.localcontentmigration.EligibilityHelper
Expand Down Expand Up @@ -42,6 +43,7 @@ class LocalMigrationOrchestrator @Inject constructor(
private val sitesMigrationHelper: SitesMigrationHelper,
private val localPostsHelper: LocalPostsHelper,
private val eligibilityHelper: EligibilityHelper,
private val bloggingRemindersHelper: BloggingRemindersHelper,
) {
fun tryLocalMigration(migrationStateFlow: MutableStateFlow<LocalMigrationState>) {
eligibilityHelper.validate()
Expand All @@ -50,6 +52,7 @@ class LocalMigrationOrchestrator @Inject constructor(
.then(userFlagsHelper::migrateUserFlags)
.then(readerSavedPostsHelper::migrateReaderSavedPosts)
.then(localPostsHelper::migratePosts)
.then(bloggingRemindersHelper::migrateBloggingReminders)
.orElse { error ->
migrationStateFlow.value = when (error) {
is Ineligibility -> Ineligible
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
import org.wordpress.android.WordPress;
import org.wordpress.android.analytics.AnalyticsTracker;
import org.wordpress.android.analytics.AnalyticsTracker.Stat;
import org.wordpress.android.bloggingreminders.resolver.BloggingRemindersResolver;
import org.wordpress.android.fluxc.Dispatcher;
import org.wordpress.android.fluxc.generated.AccountActionBuilder;
import org.wordpress.android.fluxc.generated.SiteActionBuilder;
Expand Down Expand Up @@ -172,7 +171,6 @@
import static org.wordpress.android.ui.JetpackConnectionSource.NOTIFICATIONS;

import dagger.hilt.android.AndroidEntryPoint;
import kotlin.Unit;

/**
* Main activity which hosts sites, reader, me and notifications pages
Expand Down Expand Up @@ -264,7 +262,6 @@ public class WPMainActivity extends LocaleAwareActivity implements
@Inject WeeklyRoundupScheduler mWeeklyRoundupScheduler;
@Inject MySiteDashboardTodaysStatsCardFeatureConfig mTodaysStatsCardFeatureConfig;
@Inject QuickStartTracker mQuickStartTracker;
@Inject BloggingRemindersResolver mBloggingRemindersResolver;
@Inject JetpackAppMigrationFlowUtils mJetpackAppMigrationFlowUtils;
@Inject DeepLinkOpenWebLinksWithJetpackHelper mDeepLinkOpenWebLinksWithJetpackHelper;
@Inject OpenWebLinksWithJetpackFlowFeatureConfig mOpenWebLinksWithJetpackFlowFeatureConfig;
Expand Down Expand Up @@ -1657,9 +1654,6 @@ public void onSiteChanged(OnSiteChanged event) {
mSelectedSiteRepository.updateSite(site);
}
}
mBloggingRemindersResolver.trySyncBloggingReminders(
() -> Unit.INSTANCE, () -> Unit.INSTANCE
);
}

@SuppressWarnings("unused")
Expand Down
Loading