From 2905f3eb583abbd419d617d24742c29677d86860 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 9 Jan 2024 12:01:15 +0800 Subject: [PATCH] Use the new highlightChanges queue for highlight operations --- android/Omnivore/app/build.gradle | 4 +- .../dataService/HighlightActionHandlers.kt | 52 ++++--------------- .../dataService/SyncOfflineChanges.kt | 52 ++++++++----------- .../omnivore/networking/HighlightMutations.kt | 35 ++++++++++--- .../app/omnivore/omnivore/ExampleUnitTest.kt | 17 ------ 5 files changed, 62 insertions(+), 98 deletions(-) delete mode 100644 android/Omnivore/app/src/test/java/app/omnivore/omnivore/ExampleUnitTest.kt diff --git a/android/Omnivore/app/build.gradle b/android/Omnivore/app/build.gradle index 7fbe9d35f..7e1450262 100644 --- a/android/Omnivore/app/build.gradle +++ b/android/Omnivore/app/build.gradle @@ -19,8 +19,8 @@ android { applicationId "app.omnivore.omnivore" minSdk 26 targetSdk 33 - versionCode 176 - versionName "0.0.176" + versionCode 178 + versionName "0.0.178" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt index 4bf4d04ca..78025a3d0 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt @@ -38,7 +38,7 @@ suspend fun DataService.createWebHighlight(jsonString: String, colorName: String highlight.serverSyncStatus = ServerSyncStatus.NEEDS_CREATION.rawValue - saveHighlightChange(db.highlightChangesDao(), createHighlightInput.articleId, highlight) + val highlightChange = saveHighlightChange(db.highlightChangesDao(), createHighlightInput.articleId, highlight) val crossRef = SavedItemAndHighlightCrossRef( highlightId = createHighlightInput.id, @@ -48,12 +48,7 @@ suspend fun DataService.createWebHighlight(jsonString: String, colorName: String db.highlightDao().insertAll(listOf(highlight)) db.savedItemAndHighlightCrossRefDao().insertAll(listOf(crossRef)) - val newHighlight = networker.createHighlight(createHighlightInput) - - newHighlight?.let { - db.highlightDao().update(it) - db.highlightChangesDao().deleteById(highlightId = highlight.highlightId) - } + performHighlightChange(highlightChange) } } @@ -81,7 +76,7 @@ suspend fun DataService.createNoteHighlight(savedItemId: String, note: String): highlight.serverSyncStatus = ServerSyncStatus.NEEDS_CREATION.rawValue - saveHighlightChange(db.highlightChangesDao(), savedItemId, highlight) + val highlightChange = saveHighlightChange(db.highlightChangesDao(), savedItemId, highlight) val crossRef = SavedItemAndHighlightCrossRef( highlightId = createHighlightId, @@ -91,21 +86,7 @@ suspend fun DataService.createNoteHighlight(savedItemId: String, note: String): db.highlightDao().insertAll(listOf(highlight)) db.savedItemAndHighlightCrossRefDao().insertAll(listOf(crossRef)) - val newHighlight = networker.createHighlight(input = CreateHighlightParams( - type = HighlightType.NOTE, - articleId = savedItemId, - id = createHighlightId, - shortId = shortId, - quote = null, - patch = null, - annotation = note, - highlightPositionAnchorIndex = 0, - highlightPositionPercent = 0.0 - ).asCreateHighlightInput()) - - newHighlight?.let { - db.highlightDao().update(it) - } + performHighlightChange(highlightChange) } return createHighlightId @@ -163,6 +144,7 @@ suspend fun DataService.updateWebHighlight(jsonString: String) { if (updateHighlightParams.highlightId == null || updateHighlightParams.libraryItemId == null) { Log.d("error","ERROR INVALID HIGHLIGHT DATA") + return } withContext(Dispatchers.IO) { @@ -172,19 +154,12 @@ suspend fun DataService.updateWebHighlight(jsonString: String) { highlight.serverSyncStatus = ServerSyncStatus.NEEDS_UPDATE.rawValue db.highlightDao().update(highlight) - saveHighlightChange(db.highlightChangesDao(), updateHighlightParams.libraryItemId ?: "", highlight) - - val isUpdatedOnServer = networker.updateHighlight(updateHighlightParams.asUpdateHighlightInput()) - - if (isUpdatedOnServer) { - highlight.serverSyncStatus = ServerSyncStatus.IS_SYNCED.rawValue - db.highlightDao().update(highlight) - } + val highlightChange = saveHighlightChange(db.highlightChangesDao(), updateHighlightParams.libraryItemId ?: "", highlight) + performHighlightChange(highlightChange) } } suspend fun DataService.deleteHighlightFromJSON(jsonString: String) { - Log.d("sync", "DELETION STRING: " + jsonString) val deleteHighlightParams = Gson().fromJson(jsonString, DeleteHighlightParams::class.java) deleteHighlight(deleteHighlightParams.libraryItemId, deleteHighlightParams.highlightId) } @@ -197,17 +172,8 @@ private suspend fun DataService.deleteHighlight(savedItemId: String, highlightID highlight.serverSyncStatus = ServerSyncStatus.NEEDS_DELETION.rawValue db.highlightDao().update(highlight) - saveHighlightChange(db.highlightChangesDao(), savedItemId, highlight) - - val isUpdatedOnServer = networker.deleteHighlights(listOf(highlightID)) - Log.d("sync","DELETING HIGHLIGHT" + highlightID) - - if (isUpdatedOnServer) { - Log.d("sync","DELETED HIGHLIGHT" + highlightID) - db.highlightDao().deleteById(highlightId = highlightID) - } - } ?: run { - Log.d("sync","Could not find highlight for deletion" + savedItemId + "," + highlightID) + val highlightChange = saveHighlightChange(db.highlightChangesDao(), savedItemId, highlight) + performHighlightChange(highlightChange) } } } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SyncOfflineChanges.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SyncOfflineChanges.kt index 3ae8b3f68..7db486b82 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SyncOfflineChanges.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/SyncOfflineChanges.kt @@ -6,6 +6,7 @@ import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput import app.omnivore.omnivore.models.ServerSyncStatus import app.omnivore.omnivore.networking.* import app.omnivore.omnivore.persistence.entities.Highlight +import app.omnivore.omnivore.persistence.entities.HighlightChange import app.omnivore.omnivore.persistence.entities.SavedItem import app.omnivore.omnivore.persistence.entities.highlightChangeToHighlight import com.apollographql.apollo3.api.Optional @@ -17,12 +18,16 @@ suspend fun DataService.startSyncChannels() { for (savedItem in savedItemSyncChannel) { syncSavedItem(savedItem) } +} - for (highlight in highlightSyncChannel) { - syncHighlight(highlight) +suspend fun DataService.performHighlightChange(highlightChange: HighlightChange) { + val highlight = highlightChangeToHighlight(highlightChange) + if (syncHighlightChange(highlightChange)) { + db.highlightChangesDao().deleteById(highlight.highlightId) } } + suspend fun DataService.syncOfflineItemsWithServerIfNeeded() { val unSyncedSavedItems = db.savedItemDao().getUnSynced() val unSyncedHighlights = db.highlightChangesDao().getUnSynced() @@ -33,22 +38,7 @@ suspend fun DataService.syncOfflineItemsWithServerIfNeeded() { } for (change in unSyncedHighlights) { - val highlight = highlightChangeToHighlight(change) - Log.d("sync","UNSYNC CHANGE: " + highlight.serverSyncStatus + " HIGHLIGHT: " + highlight) - - when (change.serverSyncStatus) { - ServerSyncStatus.NEEDS_CREATION.rawValue -> { - highlight.serverSyncStatus = change.serverSyncStatus - if (syncHighlight(highlight)) { - db.highlightChangesDao().deleteById(highlight.highlightId) - } - } - else -> { - db.highlightChangesDao().deleteById(highlight.highlightId) - } - } - delay(250) - // highlightSyncChannel.send(highlight) + performHighlightChange(change) } } @@ -100,7 +90,9 @@ private suspend fun DataService.syncSavedItem(item: SavedItem) { } } -private suspend fun DataService.syncHighlight(highlight: Highlight): Boolean { +private suspend fun DataService.syncHighlightChange(highlightChange: HighlightChange): Boolean { + val highlight = highlightChangeToHighlight(highlightChange) + fun updateSyncStatus(status: ServerSyncStatus) { highlight.serverSyncStatus = status.rawValue db.highlightDao().update(highlight) @@ -109,7 +101,6 @@ private suspend fun DataService.syncHighlight(highlight: Highlight): Boolean { when (highlight.serverSyncStatus) { ServerSyncStatus.NEEDS_DELETION.rawValue -> { updateSyncStatus(ServerSyncStatus.IS_SYNCING) - val isDeletedOnServer = networker.deleteHighlights(listOf(highlight.highlightId)) if (isDeletedOnServer) { @@ -119,7 +110,10 @@ private suspend fun DataService.syncHighlight(highlight: Highlight): Boolean { } return isDeletedOnServer != null } + ServerSyncStatus.NEEDS_UPDATE.rawValue -> { + Log.d("sync", "creating highlight update change: ${highlightChange}") + updateSyncStatus(ServerSyncStatus.IS_SYNCING) val isUpdatedOnServer = networker.updateHighlight( @@ -129,6 +123,7 @@ private suspend fun DataService.syncHighlight(highlight: Highlight): Boolean { sharedAt = Optional.absent() ) ) + Log.d("sync", "sycn.updateHighlight result: ${isUpdatedOnServer}") if (isUpdatedOnServer) { updateSyncStatus(ServerSyncStatus.IS_SYNCED) @@ -137,31 +132,30 @@ private suspend fun DataService.syncHighlight(highlight: Highlight): Boolean { } return isUpdatedOnServer != null } + ServerSyncStatus.NEEDS_CREATION.rawValue -> { - Log.d("sync", "CREATING") + Log.d("sync", "creating highlight create change: ${highlightChange}") updateSyncStatus(ServerSyncStatus.IS_SYNCING) - val savedItemID = db.savedItemAndHighlightCrossRefDao() - .associatedSavedItemID(highlightId = highlight.highlightId) - - val isCreatedOnServer = networker.createHighlight( + val createResult = networker.createHighlight( CreateHighlightInput( annotation = Optional.presentIfNotNull(highlight.annotation), - articleId = savedItemID ?: "", + articleId = highlightChange.savedItemId, id = highlight.highlightId, patch = Optional.presentIfNotNull(highlight.patch), quote = Optional.presentIfNotNull(highlight.quote), shortId = highlight.shortId ) ) - Log.d("sync", "isCreatedOnServer: " + isCreatedOnServer) + Log.d("sync", "sycn.createResult: " + createResult) - if (isCreatedOnServer != null) { + if (createResult.newHighlight != null || createResult.alreadyExists) { updateSyncStatus(ServerSyncStatus.IS_SYNCED) + return true } else { updateSyncStatus(ServerSyncStatus.NEEDS_UPDATE) + return false } - return isCreatedOnServer != null } else -> return false } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/networking/HighlightMutations.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/networking/HighlightMutations.kt index f1e5c2df5..f1da39d72 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/networking/HighlightMutations.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/networking/HighlightMutations.kt @@ -5,6 +5,7 @@ import app.omnivore.omnivore.graphql.generated.CreateHighlightMutation import app.omnivore.omnivore.graphql.generated.DeleteHighlightMutation import app.omnivore.omnivore.graphql.generated.MergeHighlightMutation import app.omnivore.omnivore.graphql.generated.UpdateHighlightMutation +import app.omnivore.omnivore.graphql.generated.type.CreateHighlightErrorCode import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput import app.omnivore.omnivore.graphql.generated.type.HighlightType import app.omnivore.omnivore.graphql.generated.type.MergeHighlightInput @@ -136,18 +137,26 @@ suspend fun Networker.createWebHighlight(jsonString: String): Boolean { return createHighlight(input) != null } -suspend fun Networker.createHighlight(input: CreateHighlightInput): Highlight? { - Log.d("Loggo", "created highlight input: $input") +data class CreateHighlightResult( + val failedToCreate: Boolean, + val alreadyExists: Boolean, + val newHighlight: Highlight? +) + +suspend fun Networker.createHighlight(input: CreateHighlightInput): CreateHighlightResult { + Log.d("sync", "creating highlight with input: ${input}") try { val result = authenticatedApolloClient().mutation(CreateHighlightMutation(input)).execute() - Log.d("Loggo", "result: ${result.data}") - + Log.d("sync", "result: ${result.data}") val createdHighlight = result.data?.createHighlight?.onCreateHighlightSuccess?.highlight if (createdHighlight != null) { - return Highlight( + return CreateHighlightResult( + failedToCreate = false, + alreadyExists = false, + newHighlight = Highlight( type = createdHighlight.highlightFields.type.toString(), highlightId = createdHighlight.highlightFields.id, shortId = createdHighlight.highlightFields.shortId, @@ -163,10 +172,22 @@ suspend fun Networker.createHighlight(input: CreateHighlightInput): Highlight? { highlightPositionPercent = createdHighlight.highlightFields.highlightPositionPercent, highlightPositionAnchorIndex = createdHighlight.highlightFields.highlightPositionAnchorIndex ) + ) } else { - return null + if (result.data?.createHighlight?.onCreateHighlightError?.errorCodes?.first() == CreateHighlightErrorCode.ALREADY_EXISTS) { + return CreateHighlightResult( + failedToCreate = false, + alreadyExists = true, + newHighlight = null + ) + } } } catch (e: java.lang.Exception) { - return null + Log.d("sync", "error creating highlight: " +e) } + return CreateHighlightResult( + failedToCreate = true, + alreadyExists = false, + newHighlight = null + ) } diff --git a/android/Omnivore/app/src/test/java/app/omnivore/omnivore/ExampleUnitTest.kt b/android/Omnivore/app/src/test/java/app/omnivore/omnivore/ExampleUnitTest.kt deleted file mode 100644 index 10b8f0648..000000000 --- a/android/Omnivore/app/src/test/java/app/omnivore/omnivore/ExampleUnitTest.kt +++ /dev/null @@ -1,17 +0,0 @@ -package app.omnivore.omnivore - -import org.junit.Test - -import org.junit.Assert.* - -/** - * Example local unit test, which will execute on the development machine (host). - * - * See [testing documentation](http://d.android.com/tools/testing). - */ -class ExampleUnitTest { - @Test - fun addition_isCorrect() { - assertEquals(4, 2 + 2) - } -}