From 4c15c4253cfc4dd7c07fff8493ee8b9a34765820 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Thu, 8 Aug 2019 12:04:41 +0200 Subject: [PATCH 1/2] Refactor get upload action methods --- .../android/ui/main/WPMainActivity.java | 3 + .../android/ui/posts/PostListMainViewModel.kt | 7 +- .../ui/posts/PostListUploadStatusTracker.kt | 23 +++--- .../android/ui/posts/PostUploadAction.kt | 11 ++- .../android/ui/posts/PostsListActivity.kt | 5 +- .../ui/posts/RemotePreviewLogicHelper.kt | 19 ++--- .../android/ui/uploads/PostUploadHandler.java | 3 +- .../android/ui/uploads/UploadActionUseCase.kt | 77 +++++++++++++++++++ .../android/ui/uploads/UploadStarter.kt | 54 +------------ .../android/ui/uploads/UploadUtils.java | 25 ++---- .../viewmodel/posts/PostListViewModel.kt | 2 +- .../posts/PostListViewModelConnector.kt | 3 +- .../ui/posts/PostListMainViewModelTest.kt | 3 +- .../ui/posts/RemotePreviewLogicHelperTest.kt | 6 +- .../ui/uploads/UploadStarterConcurrentTest.kt | 5 +- .../android/ui/uploads/UploadStarterTest.kt | 5 +- 16 files changed, 146 insertions(+), 105 deletions(-) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java index 992bc49d70d3..0431548e72f5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/main/WPMainActivity.java @@ -87,6 +87,7 @@ import org.wordpress.android.ui.prefs.SiteSettingsFragment; import org.wordpress.android.ui.reader.ReaderPostListFragment; import org.wordpress.android.ui.reader.ReaderPostPagerActivity; +import org.wordpress.android.ui.uploads.UploadActionUseCase; import org.wordpress.android.ui.uploads.UploadUtils; import org.wordpress.android.util.AniUtils; import org.wordpress.android.util.AppLog; @@ -169,6 +170,7 @@ public class WPMainActivity extends AppCompatActivity implements @Inject ShortcutUtils mShortcutUtils; @Inject NewsManager mNewsManager; @Inject QuickStartStore mQuickStartStore; + @Inject UploadActionUseCase mUploadActionUseCase; /* * fragments implement this if their contents can be scrolled, called when user @@ -756,6 +758,7 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) { data, post, site, + mUploadActionUseCase.getUploadAction(post), new View.OnClickListener() { @Override public void onClick(View v) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListMainViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListMainViewModel.kt index 8041497594c7..7ecdd459eb02 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListMainViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListMainViewModel.kt @@ -39,6 +39,7 @@ import org.wordpress.android.ui.posts.PostListViewLayoutType.STANDARD import org.wordpress.android.ui.posts.PostListViewLayoutTypeMenuUiState.CompactViewLayoutTypeMenuUiState import org.wordpress.android.ui.posts.PostListViewLayoutTypeMenuUiState.StandardViewLayoutTypeMenuUiState import org.wordpress.android.ui.prefs.AppPrefsWrapper +import org.wordpress.android.ui.uploads.UploadActionUseCase import org.wordpress.android.ui.uploads.UploadStarter import org.wordpress.android.util.AppLog import org.wordpress.android.util.NetworkUtilsWrapper @@ -66,6 +67,7 @@ class PostListMainViewModel @Inject constructor( private val dispatcher: Dispatcher, private val postStore: PostStore, private val accountStore: AccountStore, + uploadActionUseCase: UploadActionUseCase, uploadStore: UploadStore, mediaStore: MediaStore, private val networkUtilsWrapper: NetworkUtilsWrapper, @@ -130,7 +132,10 @@ class PostListMainViewModel @Inject constructor( private val _searchQuery = MutableLiveData() val searchQuery: LiveData = _searchQuery - private val uploadStatusTracker = PostListUploadStatusTracker(uploadStore = uploadStore) + private val uploadStatusTracker = PostListUploadStatusTracker( + uploadStore = uploadStore, + uploadActionUseCase = uploadActionUseCase + ) private val featuredImageTracker = PostListFeaturedImageTracker(dispatcher = dispatcher, mediaStore = mediaStore) private val postFetcher by lazy { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListUploadStatusTracker.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListUploadStatusTracker.kt index e305886379ca..e2ed80b80f04 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListUploadStatusTracker.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostListUploadStatusTracker.kt @@ -3,22 +3,25 @@ package org.wordpress.android.ui.posts import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.UploadStore +import org.wordpress.android.ui.uploads.UploadActionUseCase +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.DO_NOTHING +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.REMOTE_AUTO_SAVE +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD_AS_DRAFT import org.wordpress.android.ui.uploads.UploadService -import org.wordpress.android.ui.uploads.UploadStarter -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.DO_NOTHING -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.REMOTE_AUTO_SAVE -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.UPLOAD -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.UPLOAD_AS_DRAFT import org.wordpress.android.viewmodel.posts.PostListItemUploadStatus /** * This is a temporary class to make the PostListViewModel more manageable. Please feel free to refactor it any way * you see fit. */ -class PostListUploadStatusTracker(private val uploadStore: UploadStore) { +class PostListUploadStatusTracker( + private val uploadStore: UploadStore, + private val uploadActionUseCase: UploadActionUseCase +) { private val uploadStatusMap = HashMap() - fun getUploadStatus(post: PostModel, uploadStarter: UploadStarter, siteModel: SiteModel): PostListItemUploadStatus { + fun getUploadStatus(post: PostModel, siteModel: SiteModel): PostListItemUploadStatus { uploadStatusMap[post.id]?.let { return it } val uploadError = uploadStore.getUploadErrorForPost(post) val isUploadingOrQueued = UploadService.isPostUploadingOrQueued(post) @@ -32,14 +35,14 @@ class PostListUploadStatusTracker(private val uploadStore: UploadStore) { isUploadFailed = uploadStore.isFailedPost(post), hasInProgressMediaUpload = hasInProgressMediaUpload, hasPendingMediaUpload = UploadService.hasPendingMediaUploadsForPost(post), - isEligibleForAutoUpload = isEligibleForAutoUpload(uploadStarter, siteModel, post) + isEligibleForAutoUpload = isEligibleForAutoUpload(siteModel, post) ) uploadStatusMap[post.id] = newStatus return newStatus } - private fun isEligibleForAutoUpload(uploadStarter: UploadStarter, site: SiteModel, post: PostModel): Boolean { - return when (uploadStarter.getAutoUploadAction(post, site)) { + private fun isEligibleForAutoUpload(site: SiteModel, post: PostModel): Boolean { + return when (uploadActionUseCase.getAutoUploadAction(post, site)) { UPLOAD -> true UPLOAD_AS_DRAFT, REMOTE_AUTO_SAVE, DO_NOTHING -> false } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUploadAction.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUploadAction.kt index e8d5df81970b..b9fe1d8836c1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUploadAction.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostUploadAction.kt @@ -7,6 +7,7 @@ import org.wordpress.android.fluxc.Dispatcher import org.wordpress.android.fluxc.model.MediaModel import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.ui.uploads.UploadActionUseCase import org.wordpress.android.ui.uploads.UploadService import org.wordpress.android.ui.uploads.UploadUtils @@ -45,7 +46,12 @@ sealed class PostUploadAction { class CancelPostAndMediaUpload(val post: PostModel) : PostUploadAction() } -fun handleUploadAction(action: PostUploadAction, activity: Activity, snackbarAttachView: View) { +fun handleUploadAction( + action: PostUploadAction, + activity: Activity, + snackbarAttachView: View, + uploadActionUseCase: UploadActionUseCase +) { when (action) { is PostUploadAction.EditPostResult -> { UploadUtils.handleEditPostResultSnackbars( @@ -53,7 +59,8 @@ fun handleUploadAction(action: PostUploadAction, activity: Activity, snackbarAtt snackbarAttachView, action.data, action.post, - action.site + action.site, + uploadActionUseCase.getUploadAction(action.post) ) { action.publishAction() } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostsListActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostsListActivity.kt index c6263a8506ad..39a3fd6d136d 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/PostsListActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/PostsListActivity.kt @@ -37,6 +37,7 @@ import org.wordpress.android.ui.posts.BasicFragmentDialog.BasicDialogOnDismissBy import org.wordpress.android.ui.posts.BasicFragmentDialog.BasicDialogPositiveClickInterface import org.wordpress.android.ui.posts.PostListType.SEARCH import org.wordpress.android.ui.posts.adapters.AuthorSelectionAdapter +import org.wordpress.android.ui.uploads.UploadActionUseCase import org.wordpress.android.ui.utils.UiHelpers import org.wordpress.android.ui.utils.UiString import org.wordpress.android.util.AppLog @@ -58,6 +59,7 @@ class PostsListActivity : AppCompatActivity(), @Inject internal lateinit var remotePreviewLogicHelper: RemotePreviewLogicHelper @Inject internal lateinit var previewStateHelper: PreviewStateHelper @Inject internal lateinit var progressDialogHelper: ProgressDialogHelper + @Inject internal lateinit var uploadActionUseCase: UploadActionUseCase private lateinit var site: SiteModel private lateinit var viewModel: PostListMainViewModel @@ -256,7 +258,8 @@ class PostsListActivity : AppCompatActivity(), handleUploadAction( uploadAction, this@PostsListActivity, - findViewById(R.id.coordinator) + findViewById(R.id.coordinator), + uploadActionUseCase ) } }) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt index e6b2b1d563ad..a52c3070461f 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt @@ -5,11 +5,11 @@ import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.ActivityLauncherWrapper import org.wordpress.android.ui.WPWebViewUsageCategory -import org.wordpress.android.ui.uploads.UploadUtils -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.REMOTE_AUTO_SAVE -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.UPLOAD -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.UPLOAD_AS_DRAFT +import org.wordpress.android.ui.uploads.UploadActionUseCase +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.REMOTE_AUTO_SAVE +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD_AS_DRAFT import org.wordpress.android.util.NetworkUtilsWrapper import javax.inject.Inject import javax.inject.Singleton @@ -18,7 +18,8 @@ import javax.inject.Singleton class RemotePreviewLogicHelper @Inject constructor( private val networkUtilsWrapper: NetworkUtilsWrapper, private val activityLauncherWrapper: ActivityLauncherWrapper, - private val postUtilsWrapper: PostUtilsWrapper + private val postUtilsWrapper: PostUtilsWrapper, + private val uploadActionUseCase: UploadActionUseCase ) { enum class RemotePreviewType { NOT_A_REMOTE_PREVIEW, @@ -68,7 +69,7 @@ class RemotePreviewLogicHelper @Inject constructor( // (eg. during and editing session) val updatedPost = helperFunctions.updatePostIfNeeded() ?: post - val uploadAction = UploadUtils.getPostUploadAction(updatedPost) + val uploadAction = uploadActionUseCase.getUploadAction(updatedPost) return when { shouldUpload(updatedPost, uploadAction) -> { @@ -124,11 +125,11 @@ class RemotePreviewLogicHelper @Inject constructor( } } - private fun shouldUpload(post: PostModel, action: PostUploadAction): Boolean { + private fun shouldUpload(post: PostModel, action: UploadAction): Boolean { return (post.isLocallyChanged || post.isLocalDraft) && (action == UPLOAD_AS_DRAFT || action == UPLOAD) } - private fun shouldRemoteAutoSave(post: PostModel, action: PostUploadAction): Boolean { + private fun shouldRemoteAutoSave(post: PostModel, action: UploadAction): Boolean { return post.isLocallyChanged && action == REMOTE_AUTO_SAVE } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/uploads/PostUploadHandler.java b/WordPress/src/main/java/org/wordpress/android/ui/uploads/PostUploadHandler.java index a4692080f935..8c4d4e2cd852 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/uploads/PostUploadHandler.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/uploads/PostUploadHandler.java @@ -80,6 +80,7 @@ public class PostUploadHandler implements UploadHandler { @Inject PostStore mPostStore; @Inject MediaStore mMediaStore; @Inject UiHelpers mUiHelpers; + @Inject UploadActionUseCase mUploadActionUseCase; PostUploadHandler(PostUploadNotifier postUploadNotifier) { ((WordPress) WordPress.getContext().getApplicationContext()).component().inject(this); @@ -266,7 +267,7 @@ protected Boolean doInBackground(PostModel... posts) { RemotePostPayload payload = new RemotePostPayload(mPost, mSite); - switch (UploadUtils.getPostUploadAction(mPost)) { + switch (mUploadActionUseCase.getUploadAction(mPost)) { case UPLOAD: AppLog.d(T.POSTS, "Invoking newPushPostAction. Post: " + mPost.getTitle() + " status: " + mPost.getStatus()); diff --git a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt new file mode 100644 index 000000000000..d2114863b575 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt @@ -0,0 +1,77 @@ +package org.wordpress.android.ui.uploads + +import org.wordpress.android.fluxc.model.PostModel +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.store.UploadStore +import org.wordpress.android.ui.posts.PostUtilsWrapper +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.DO_NOTHING +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.REMOTE_AUTO_SAVE +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD_AS_DRAFT +import org.wordpress.android.util.DateTimeUtils +import java.util.Date +import javax.inject.Inject +import javax.inject.Singleton + +private const val MAXIMUM_AUTO_UPLOAD_RETRIES = 10 +private const val TWO_DAYS_IN_MILLIS = 1000 * 60 * 60 * 24 * 2 + +@Singleton +class UploadActionUseCase @Inject constructor( + private val uploadStore: UploadStore, + private val postUtilsWrapper: PostUtilsWrapper, + private val uploadServiceFacade: UploadServiceFacade +) { + enum class UploadAction { + REMOTE_AUTO_SAVE, UPLOAD_AS_DRAFT, UPLOAD, DO_NOTHING + } + + fun getAutoUploadAction(post: PostModel, site: SiteModel): UploadAction { + val twoDaysAgoTimestamp = Date().time - TWO_DAYS_IN_MILLIS + // Don't auto-upload/save changes which are older than 2 days + if (DateTimeUtils.timestampFromIso8601Millis(post.dateLocallyChanged) < twoDaysAgoTimestamp) { + return DO_NOTHING + } + + // Do not auto-upload empty post + if (!postUtilsWrapper.isPublishable(post)) { + return DO_NOTHING + } + + // Do not auto-upload post which is in conflict with remote + if (postUtilsWrapper.isPostInConflictWithRemote(post)) { + return DO_NOTHING + } + + // Do not auto-upload post which we already tried to upload certain number of times + if (uploadStore.getNumberOfPostUploadErrorsOrCancellations(post) >= MAXIMUM_AUTO_UPLOAD_RETRIES) { + return DO_NOTHING + } + + // Do not auto-upload post which is currently being uploaded + if (uploadServiceFacade.isPostUploadingOrQueued(post)) { + return DO_NOTHING + } + + val action = getUploadAction(post) + // Don't remoteAutoSave changes which were already remoteAutoSaved or when on a self-hosted site + if (action == REMOTE_AUTO_SAVE && + (UploadUtils.postLocalChangesAlreadyRemoteAutoSaved(post) || !site.isUsingWpComRestApi)) { + return DO_NOTHING + } + + return action + } + + fun getUploadAction(post: PostModel): UploadAction { + return when { + post.changesConfirmedContentHashcode == post.contentHashcode() -> + // We are sure we can push the post as the user has explicitly confirmed the changes + UPLOAD + post.isLocalDraft -> + // Local draft can always be uploaded as DRAFT as it doesn't exist on the server yet + UPLOAD_AS_DRAFT + else -> REMOTE_AUTO_SAVE + } + } +} diff --git a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadStarter.kt b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadStarter.kt index d5b9bd094e39..be731d9a34c1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadStarter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadStarter.kt @@ -14,33 +14,24 @@ import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex -import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.PageStore import org.wordpress.android.fluxc.store.PostStore import org.wordpress.android.fluxc.store.SiteStore -import org.wordpress.android.fluxc.store.UploadStore import org.wordpress.android.modules.BG_THREAD import org.wordpress.android.modules.IO_THREAD import org.wordpress.android.testing.OpenForTesting -import org.wordpress.android.ui.posts.PostUtilsWrapper -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.DO_NOTHING -import org.wordpress.android.ui.uploads.UploadUtils.PostUploadAction.REMOTE_AUTO_SAVE +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.DO_NOTHING import org.wordpress.android.util.AppLog import org.wordpress.android.util.CrashLoggingUtils -import org.wordpress.android.util.DateTimeUtils import org.wordpress.android.util.NetworkUtilsWrapper import org.wordpress.android.util.skip import org.wordpress.android.viewmodel.helpers.ConnectionStatus -import java.util.Date import javax.inject.Inject import javax.inject.Named import javax.inject.Singleton import kotlin.coroutines.CoroutineContext -private const val TWO_DAYS_IN_MILLIS = 1000 * 60 * 60 * 24 * 2 - /** * Automatically uploads local drafts. * @@ -59,16 +50,14 @@ class UploadStarter @Inject constructor( private val postStore: PostStore, private val pageStore: PageStore, private val siteStore: SiteStore, - private val uploadStore: UploadStore, + private val uploadActionUseCase: UploadActionUseCase, @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher, @Named(IO_THREAD) private val ioDispatcher: CoroutineDispatcher, private val uploadServiceFacade: UploadServiceFacade, private val networkUtilsWrapper: NetworkUtilsWrapper, - private val postUtilsWrapper: PostUtilsWrapper, private val connectionStatus: LiveData ) : CoroutineScope { private val job = Job() - private val MAXIMUM_AUTO_UPLOAD_RETRIES = 10 /** * When the app comes to foreground both `queueUploadFromAllSites` and `queueUploadFromSite` are invoked. @@ -161,7 +150,7 @@ class UploadStarter @Inject constructor( postsAndPages .asSequence() .filter { - getAutoUploadAction(it, site) != DO_NOTHING + uploadActionUseCase.getAutoUploadAction(it, site) != DO_NOTHING } .toList() .forEach { post -> @@ -178,41 +167,4 @@ class UploadStarter @Inject constructor( mutex.unlock() } } - - public fun getAutoUploadAction(post: PostModel, site: SiteModel): PostUploadAction { - val twoDaysAgoTimestamp = Date().time - TWO_DAYS_IN_MILLIS - // Don't auto-upload/save changes which are older than 2 days - if (DateTimeUtils.timestampFromIso8601Millis(post.dateLocallyChanged) < twoDaysAgoTimestamp) { - return DO_NOTHING - } - - // Do not auto-upload empty post - if (!postUtilsWrapper.isPublishable(post)) { - return DO_NOTHING - } - - // Do not auto-upload post which is in conflict with remote - if (postUtilsWrapper.isPostInConflictWithRemote(post)) { - return DO_NOTHING - } - - // Do not auto-upload post which we already tried to upload certain number of times - if (uploadStore.getNumberOfPostUploadErrorsOrCancellations(post) >= MAXIMUM_AUTO_UPLOAD_RETRIES) { - return DO_NOTHING - } - - // Do not auto-upload post which is currently being uploaded - if (uploadServiceFacade.isPostUploadingOrQueued(post)) { - return DO_NOTHING - } - - val action = UploadUtils.getPostUploadAction(post) - // Don't remoteAutoSave changes which were already remoteAutoSaved or when on a self-hosted site - if (action == REMOTE_AUTO_SAVE && - (UploadUtils.postLocalChangesAlreadyRemoteAutoSaved(post) || !site.isUsingWpComRestApi)) { - return DO_NOTHING - } - - return action - } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadUtils.java b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadUtils.java index 7b892d2c2523..1ebceab863b0 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadUtils.java +++ b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadUtils.java @@ -26,6 +26,7 @@ import org.wordpress.android.ui.posts.EditPostActivity; import org.wordpress.android.ui.posts.PostUtils; import org.wordpress.android.ui.prefs.AppPrefs; +import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction; import org.wordpress.android.ui.utils.UiString; import org.wordpress.android.ui.utils.UiString.UiStringRes; import org.wordpress.android.util.AppLog; @@ -44,10 +45,6 @@ public class UploadUtils { private static final int K_SNACKBAR_WAIT_TIME_MS = 5000; - public enum PostUploadAction { - REMOTE_AUTO_SAVE, UPLOAD_AS_DRAFT, UPLOAD, DO_NOTHING - } - /** * Returns a post-type specific error message string. */ @@ -117,6 +114,7 @@ public static void handleEditPostResultSnackbars(@NonNull final Activity activit @NonNull Intent data, @NonNull final PostModel post, @NonNull final SiteModel site, + @NonNull final UploadAction uploadAction, View.OnClickListener publishPostListener) { boolean hasChanges = data.getBooleanExtra(EditPostActivity.EXTRA_HAS_CHANGES, false); if (!hasChanges) { @@ -129,7 +127,7 @@ public static void handleEditPostResultSnackbars(@NonNull final Activity activit // The network is not available, we can enqueue a request to upload local changes later UploadWorkerKt.enqueueUploadWorkRequestForSite(site); // And tell the user about it - showSnackbar(snackbarAttachView, getDeviceOfflinePostNotUploadedMessage(post)); + showSnackbar(snackbarAttachView, getDeviceOfflinePostNotUploadedMessage(post, uploadAction)); return; } @@ -405,8 +403,9 @@ public void onClick(View view) { } @StringRes - private static int getDeviceOfflinePostNotUploadedMessage(PostModel post) { - if (getPostUploadAction(post) != PostUploadAction.UPLOAD) { + private static int getDeviceOfflinePostNotUploadedMessage(@NonNull final PostModel post, + @NonNull final UploadAction uploadAction) { + if (uploadAction != UploadAction.UPLOAD) { return R.string.error_publish_no_network; } else { switch (PostStatus.fromPost(post)) { @@ -428,18 +427,6 @@ private static int getDeviceOfflinePostNotUploadedMessage(PostModel post) { throw new RuntimeException("This code should be unreachable. Missing case in switch statement."); } - public static PostUploadAction getPostUploadAction(PostModel post) { - if (post.getChangesConfirmedContentHashcode() == post.contentHashcode()) { - // We are sure we can push the post as the user has explicitly confirmed the changes - return PostUploadAction.UPLOAD; - } else if (post.isLocalDraft()) { - // Local draft can always be uploaded as DRAFT as it doesn't exist on the server yet - return PostUploadAction.UPLOAD_AS_DRAFT; - } else { - return PostUploadAction.REMOTE_AUTO_SAVE; - } - } - public static boolean postLocalChangesAlreadyRemoteAutoSaved(PostModel post) { return post.getAutoSaveModified() != null && DateTimeUtils.dateFromIso8601(post.getDateLocallyChanged()) diff --git a/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModel.kt b/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModel.kt index 7e7b3b037ab2..d1e0d2e17700 100644 --- a/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModel.kt @@ -355,7 +355,7 @@ class PostListViewModel @Inject constructor( private fun transformPostModelToPostListItemUiState(post: PostModel) = listItemUiStateHelper.createPostListItemUiState( post = post, - uploadStatus = connector.getUploadStatus(post, uploadStarter, connector.site), + uploadStatus = connector.getUploadStatus(post, connector.site), unhandledConflicts = connector.doesPostHaveUnhandledConflict(post), capabilitiesToPublish = connector.site.hasCapabilityPublishPosts, statsSupported = isStatsSupported, diff --git a/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModelConnector.kt b/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModelConnector.kt index 1b249db106d2..18d68dc62ccd 100644 --- a/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModelConnector.kt +++ b/WordPress/src/main/java/org/wordpress/android/viewmodel/posts/PostListViewModelConnector.kt @@ -4,13 +4,12 @@ import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.posts.PostActionHandler import org.wordpress.android.ui.posts.PostListType -import org.wordpress.android.ui.uploads.UploadStarter class PostListViewModelConnector( val site: SiteModel, val postListType: PostListType, val postActionHandler: PostActionHandler, - val getUploadStatus: (PostModel, UploadStarter, SiteModel) -> PostListItemUploadStatus, + val getUploadStatus: (PostModel, SiteModel) -> PostListItemUploadStatus, val doesPostHaveUnhandledConflict: (PostModel) -> Boolean, val postFetcher: PostFetcher, private val getFeaturedImageUrl: (site: SiteModel, featuredImageId: Long) -> String? diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/PostListMainViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/PostListMainViewModelTest.kt index 9fe5d7d7fa37..cf95c724de21 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/PostListMainViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/PostListMainViewModelTest.kt @@ -44,7 +44,8 @@ class PostListMainViewModelTest : BaseUnitTest() { mainDispatcher = Dispatchers.Unconfined, bgDispatcher = Dispatchers.Unconfined, postListEventListenerFactory = mock(), - uploadStarter = uploadStarter + uploadStarter = uploadStarter, + uploadActionUseCase = mock() ) } diff --git a/WordPress/src/test/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelperTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelperTest.kt index 6b731ecda4b6..10d3e967f06f 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelperTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelperTest.kt @@ -20,6 +20,7 @@ import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.ActivityLauncherWrapper import org.wordpress.android.ui.WPWebViewUsageCategory import org.wordpress.android.ui.posts.RemotePreviewLogicHelper.RemotePreviewHelperFunctions +import org.wordpress.android.ui.uploads.UploadActionUseCase import org.wordpress.android.util.NetworkUtilsWrapper @RunWith(MockitoJUnitRunner::class) @@ -43,6 +44,8 @@ class RemotePreviewLogicHelperTest { @Mock private lateinit var postUtilsWrapper: PostUtilsWrapper + private var uploadActionUseCase = UploadActionUseCase(mock(), mock(), mock()) + private lateinit var remotePreviewLogicHelper: RemotePreviewLogicHelper @Before @@ -50,7 +53,8 @@ class RemotePreviewLogicHelperTest { remotePreviewLogicHelper = RemotePreviewLogicHelper( networkUtilsWrapper, activityLauncherWrapper, - postUtilsWrapper + postUtilsWrapper, + uploadActionUseCase ) doReturn(true).whenever(site).isUsingWpComRestApi diff --git a/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterConcurrentTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterConcurrentTest.kt index bdd83cefb148..3d2911ce0ac9 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterConcurrentTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterConcurrentTest.kt @@ -74,13 +74,12 @@ class UploadStarterConcurrentTest { postStore = postStore, pageStore = pageStore, siteStore = mock(), - uploadStore = mock(), bgDispatcher = Dispatchers.Default, ioDispatcher = Dispatchers.IO, networkUtilsWrapper = createMockedNetworkUtilsWrapper(), - postUtilsWrapper = createMockedPostUtilsWrapper(), connectionStatus = mock(), - uploadServiceFacade = uploadServiceFacade + uploadServiceFacade = uploadServiceFacade, + uploadActionUseCase = UploadActionUseCase(mock(), createMockedPostUtilsWrapper(), uploadServiceFacade) ) private companion object Fixtures { diff --git a/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterTest.kt index d95d8e04fd26..22d758effa91 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/uploads/UploadStarterTest.kt @@ -477,13 +477,12 @@ class UploadStarterTest { postStore = postStore, pageStore = pageStore, siteStore = siteStore, - uploadStore = uploadStore, bgDispatcher = Dispatchers.Unconfined, ioDispatcher = Dispatchers.Unconfined, networkUtilsWrapper = createMockedNetworkUtilsWrapper(), - postUtilsWrapper = postUtilsWrapper, connectionStatus = connectionStatus, - uploadServiceFacade = uploadServiceFacade + uploadServiceFacade = uploadServiceFacade, + uploadActionUseCase = UploadActionUseCase(uploadStore, postUtilsWrapper, uploadServiceFacade) ) private companion object Fixtures { From ae4222197ce71d82504e4cd53a2e45b9ce731ea6 Mon Sep 17 00:00:00 2001 From: malinajirka Date: Thu, 8 Aug 2019 15:20:37 +0200 Subject: [PATCH 2/2] Replace Singleton annotation with Reusable --- .../wordpress/android/ui/posts/RemotePreviewLogicHelper.kt | 4 ++-- .../org/wordpress/android/ui/uploads/UploadActionUseCase.kt | 4 ++-- .../java/org/wordpress/android/util/NetworkUtilsWrapper.kt | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt b/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt index a52c3070461f..de91554afc48 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/posts/RemotePreviewLogicHelper.kt @@ -1,6 +1,7 @@ package org.wordpress.android.ui.posts import android.app.Activity +import dagger.Reusable import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.ActivityLauncherWrapper @@ -12,9 +13,8 @@ import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD_AS_DRAFT import org.wordpress.android.util.NetworkUtilsWrapper import javax.inject.Inject -import javax.inject.Singleton -@Singleton +@Reusable class RemotePreviewLogicHelper @Inject constructor( private val networkUtilsWrapper: NetworkUtilsWrapper, private val activityLauncherWrapper: ActivityLauncherWrapper, diff --git a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt index d2114863b575..a0be62a13033 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/uploads/UploadActionUseCase.kt @@ -1,5 +1,6 @@ package org.wordpress.android.ui.uploads +import dagger.Reusable import org.wordpress.android.fluxc.model.PostModel import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.fluxc.store.UploadStore @@ -11,12 +12,11 @@ import org.wordpress.android.ui.uploads.UploadActionUseCase.UploadAction.UPLOAD_ import org.wordpress.android.util.DateTimeUtils import java.util.Date import javax.inject.Inject -import javax.inject.Singleton private const val MAXIMUM_AUTO_UPLOAD_RETRIES = 10 private const val TWO_DAYS_IN_MILLIS = 1000 * 60 * 60 * 24 * 2 -@Singleton +@Reusable class UploadActionUseCase @Inject constructor( private val uploadStore: UploadStore, private val postUtilsWrapper: PostUtilsWrapper, diff --git a/WordPress/src/main/java/org/wordpress/android/util/NetworkUtilsWrapper.kt b/WordPress/src/main/java/org/wordpress/android/util/NetworkUtilsWrapper.kt index 2678e84b0012..4042abc16860 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/NetworkUtilsWrapper.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/NetworkUtilsWrapper.kt @@ -1,10 +1,10 @@ package org.wordpress.android.util +import dagger.Reusable import org.wordpress.android.WordPress import javax.inject.Inject -import javax.inject.Singleton -@Singleton +@Reusable class NetworkUtilsWrapper @Inject constructor() { /** * Returns true if a network connection is available.