From bb1efac33670353022006482e6c543f121947801 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Tue, 17 Jan 2023 21:00:06 -0800 Subject: [PATCH] update db for saved item property changes before sending updates to serevr --- .../dataService/HighlightActionHandlers.kt | 118 ++++++++++++++++++ .../ReadingProgressChangeHandler.kt | 28 +++++ .../persistence/entities/Highlight.kt | 13 +- .../persistence/entities/SavedItem.kt | 4 +- .../omnivore/ui/reader/WebReaderViewModel.kt | 20 +-- 5 files changed, 162 insertions(+), 21 deletions(-) create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt create mode 100644 android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/ReadingProgressChangeHandler.kt 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 new file mode 100644 index 000000000..4fc89f1f6 --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/HighlightActionHandlers.kt @@ -0,0 +1,118 @@ +package app.omnivore.omnivore.dataService + +import app.omnivore.omnivore.models.ServerSyncStatus +import app.omnivore.omnivore.networking.* +import app.omnivore.omnivore.persistence.entities.Highlight +import app.omnivore.omnivore.persistence.entities.SavedItemAndHighlightCrossRef +import com.google.gson.Gson +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +suspend fun DataService.createWebHighlight(jsonString: String) { + val createHighlightInput = Gson().fromJson(jsonString, CreateHighlightParams::class.java).asCreateHighlightInput() + + withContext(Dispatchers.IO) { + val highlight = Highlight( + highlightId = createHighlightInput.id, + shortId = createHighlightInput.shortId, + quote = createHighlightInput.quote, + prefix = null, + suffix = null, + patch = createHighlightInput.patch, + annotation = createHighlightInput.annotation.getOrNull(), + createdAt = null, + updatedAt = null, + createdByMe = false + ) + + highlight.serverSyncStatus = ServerSyncStatus.NEEDS_CREATION.rawValue + + val crossRef = SavedItemAndHighlightCrossRef( + highlightId = createHighlightInput.id, + savedItemId = createHighlightInput.articleId + ) + + db.savedItemAndHighlightCrossRefDao().insertAll(listOf(crossRef)) + db.highlightDao().update(highlight) + + val newHighlight = networker.createHighlight(createHighlightInput) + + newHighlight?.let { + db.highlightDao().update(it) + } + } +} + +suspend fun DataService.mergeWebHighlights(jsonString: String) { + val mergeHighlightInput = Gson().fromJson(jsonString, MergeHighlightsParams::class.java).asMergeHighlightInput() + + withContext(Dispatchers.IO) { + val highlight = db.highlightDao().findById(highlightId = mergeHighlightInput.id) ?: return@withContext + highlight.shortId = mergeHighlightInput.shortId + highlight.quote = mergeHighlightInput.quote + highlight.patch = mergeHighlightInput.patch + highlight.prefix = mergeHighlightInput.prefix.getOrNull() + highlight.annotation = mergeHighlightInput.annotation.getOrNull() + highlight.serverSyncStatus = ServerSyncStatus.NEEDS_UPDATE.rawValue + + for (highlightID in mergeHighlightInput.overlapHighlightIdList) { + deleteHighlight(highlightID) + } + + val crossRef = SavedItemAndHighlightCrossRef( + highlightId = mergeHighlightInput.id, + savedItemId = mergeHighlightInput.articleId + ) + + db.savedItemAndHighlightCrossRefDao().insertAll(listOf(crossRef)) + db.highlightDao().update(highlight) + + val isUpdatedOnServer = networker.mergeHighlights(mergeHighlightInput) + + if (isUpdatedOnServer) { + highlight.serverSyncStatus = ServerSyncStatus.IS_SYNCED.rawValue + db.highlightDao().update(highlight) + } + } +} + +suspend fun DataService.updateWebHighlight(jsonString: String) { + val updateHighlightParams = Gson().fromJson(jsonString, UpdateHighlightParams::class.java).asUpdateHighlightInput() + + withContext(Dispatchers.IO) { + val highlight = db.highlightDao().findById(highlightId = updateHighlightParams.highlightId) ?: return@withContext + + highlight.annotation = updateHighlightParams.annotation.getOrNull() + highlight.serverSyncStatus = ServerSyncStatus.NEEDS_UPDATE.rawValue + db.highlightDao().update(highlight) + + val isUpdatedOnServer = networker.updateHighlight(updateHighlightParams) + + if (isUpdatedOnServer) { + highlight.serverSyncStatus = ServerSyncStatus.IS_SYNCED.rawValue + db.highlightDao().update(highlight) + } + } +} + +suspend fun DataService.deleteHighlights(jsonString: String) { + val highlightIDs = Gson().fromJson(jsonString, DeleteHighlightParams::class.java).asIdList() + + for (highlightID in highlightIDs) { + deleteHighlight(highlightID) + } +} + +private suspend fun DataService.deleteHighlight(highlightID: String) { + withContext(Dispatchers.IO) { + val highlight = db.highlightDao().findById(highlightId = highlightID) ?: return@withContext + highlight.serverSyncStatus = ServerSyncStatus.NEEDS_DELETION.rawValue + db.highlightDao().update(highlight) + + val isUpdatedOnServer = networker.deleteHighlights(listOf(highlightID)) + + if (isUpdatedOnServer) { + db.highlightDao().deleteById(highlightId = highlightID) + } + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/ReadingProgressChangeHandler.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/ReadingProgressChangeHandler.kt new file mode 100644 index 000000000..98e175ddd --- /dev/null +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/dataService/ReadingProgressChangeHandler.kt @@ -0,0 +1,28 @@ +package app.omnivore.omnivore.dataService + +import app.omnivore.omnivore.models.ServerSyncStatus +import app.omnivore.omnivore.networking.ReadingProgressParams +import app.omnivore.omnivore.networking.updateReadingProgress +import com.google.gson.Gson +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +suspend fun DataService.updateWebReadingProgress(jsonString: String) { + val readingProgressParams = Gson().fromJson(jsonString, ReadingProgressParams::class.java) + val savedItemId = readingProgressParams.id ?: return + + withContext(Dispatchers.IO) { + val savedItem = db.savedItemDao().findById(savedItemId) ?: return@withContext + savedItem.readingProgress = readingProgressParams.readingProgressPercent ?: 0.0 + savedItem.readingProgressAnchor = readingProgressParams.readingProgressAnchorIndex ?: 0 + savedItem.serverSyncStatus = ServerSyncStatus.NEEDS_UPDATE.rawValue + db.savedItemDao().update(savedItem) + + val isUpdatedOnServer = networker.updateReadingProgress(readingProgressParams) + + if (isUpdatedOnServer) { + savedItem.serverSyncStatus = ServerSyncStatus.IS_SYNCED.rawValue + db.savedItemDao().update(savedItem) + } + } +} diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt index c69d6bf5e..757a8ee42 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/Highlight.kt @@ -7,15 +7,15 @@ import app.omnivore.omnivore.models.ServerSyncStatus @Entity data class Highlight( @PrimaryKey val highlightId: String, - val annotation: String?, + var annotation: String?, val createdAt: String?, val createdByMe: Boolean, val markedForDeletion: Boolean = false, - val patch: String, - val prefix: String?, - val quote: String, + var patch: String, + var prefix: String?, + var quote: String, var serverSyncStatus: Int = ServerSyncStatus.IS_SYNCED.rawValue, - val shortId: String, + var shortId: String, val suffix: String?, val updatedAt: String? @@ -84,6 +84,9 @@ interface HighlightDao { @Query("DELETE FROM highlight WHERE highlightId = :highlightId") fun deleteById(highlightId: String) + @Query("SELECT * FROM highlight WHERE highlightId = :highlightId") + fun findById(highlightId: String): Highlight? + @Update fun update(highlight: Highlight) } diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt index 91b3096ad..506534964 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/persistence/entities/SavedItem.kt @@ -13,8 +13,8 @@ data class SavedItem( val savedAt: String, val readAt: String?, val updatedAt: String?, - val readingProgress: Double, - val readingProgressAnchor: Int, + var readingProgress: Double, + var readingProgressAnchor: Int, val imageURLString: String?, val pageURLString: String, val descriptionText: String?, diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt index 3cde695de..dfb472e8d 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/WebReaderViewModel.kt @@ -7,10 +7,7 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.omnivore.omnivore.DatastoreKeys import app.omnivore.omnivore.DatastoreRepository -import app.omnivore.omnivore.dataService.DataService -import app.omnivore.omnivore.dataService.archiveSavedItem -import app.omnivore.omnivore.dataService.deleteSavedItem -import app.omnivore.omnivore.dataService.unarchiveSavedItem +import app.omnivore.omnivore.dataService.* import app.omnivore.omnivore.persistence.entities.SavedItem import app.omnivore.omnivore.networking.* import app.omnivore.omnivore.ui.library.SavedItemAction @@ -124,28 +121,24 @@ class WebReaderViewModel @Inject constructor( when (actionID) { "createHighlight" -> { viewModelScope.launch { - val isHighlightSynced = networker.createWebHighlight(jsonString) - Log.d("Network", "isHighlightSynced = $isHighlightSynced") + dataService.createWebHighlight(jsonString) } } "deleteHighlight" -> { Log.d("Loggo", "receive delete highlight action: $jsonString") viewModelScope.launch { - val isHighlightDeletionSynced = networker.deleteHighlight(jsonString) - Log.d("Network", "isHighlightDeletionSynced = $isHighlightDeletionSynced") + dataService.deleteHighlights(jsonString) } } "updateHighlight" -> { Log.d("Loggo", "receive update highlight action: $jsonString") viewModelScope.launch { - val isHighlightUpdateSynced = networker.updateWebHighlight(jsonString) - Log.d("Network", "isHighlightUpdateSynced = $isHighlightUpdateSynced") + dataService.updateWebHighlight(jsonString) } } "articleReadingProgress" -> { viewModelScope.launch { - val isReadingProgressSynced = networker.updateWebReadingProgress(jsonString) - Log.d("Network", "isReadingProgressSynced = $isReadingProgressSynced") + dataService.updateWebReadingProgress(jsonString) } } "annotate" -> { @@ -161,8 +154,7 @@ class WebReaderViewModel @Inject constructor( } "mergeHighlight" -> { viewModelScope.launch { - val isHighlightSynced = networker.mergeWebHighlights(jsonString) - Log.d("Network", "isMergedHighlightSynced = $isHighlightSynced") + dataService.mergeWebHighlights(jsonString) } } else -> {