From 33e45ebba9dd7e5c5e64c0c0aa69b954aaaa8b72 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Wed, 2 Nov 2022 20:48:54 -0700 Subject: [PATCH] save highlight when created from pspdfkit --- .../omnivore/networking/HighlightMutations.kt | 6 ++- .../omnivore/omnivore/ui/reader/PDFReader.kt | 45 +++++++++++++------ .../omnivore/ui/reader/PDFReaderViewModel.kt | 31 +++++++++++++ .../omnivore/ui/reader/WebReaderViewModel.kt | 2 +- 4 files changed, 69 insertions(+), 15 deletions(-) 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 8c418d63e..f41344c7b 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 @@ -3,6 +3,7 @@ package app.omnivore.omnivore.networking import android.util.Log import app.omnivore.omnivore.graphql.generated.CreateHighlightMutation import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput +import app.omnivore.omnivore.graphql.generated.type.Highlight import com.apollographql.apollo3.api.Optional import com.google.gson.Gson @@ -24,9 +25,12 @@ data class CreateHighlightParams( ) } -suspend fun Networker.createHighlight(jsonString: String): Boolean { +suspend fun Networker.createWebHighlight(jsonString: String): Boolean { val input = Gson().fromJson(jsonString, CreateHighlightParams::class.java).asCreateHighlightInput() + return createHighlight(input) +} +suspend fun Networker.createHighlight(input: CreateHighlightInput): Boolean { Log.d("Loggo", "created highlight input: $input") val result = authenticatedApolloClient().mutation(CreateHighlightMutation(input)).execute() diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReader.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReader.kt index aa6ae2e38..615be9117 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReader.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReader.kt @@ -13,6 +13,7 @@ import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.DrawableCompat import androidx.lifecycle.Observer import app.omnivore.omnivore.R +import app.omnivore.omnivore.models.Highlight import com.pspdfkit.annotations.Annotation import com.pspdfkit.annotations.AnnotationProvider import com.pspdfkit.configuration.PdfConfiguration @@ -28,6 +29,10 @@ import com.pspdfkit.ui.search.SearchResultHighlighter import com.pspdfkit.ui.search.SimpleSearchResultListener import com.pspdfkit.utils.PdfUtils import dagger.hilt.android.AndroidEntryPoint +import java.time.Duration +import java.time.LocalDateTime +import java.util.* +import kotlin.time.Duration.Companion.seconds @AndroidEntryPoint class PDFReaderActivity: AppCompatActivity(), DocumentListener { @@ -82,15 +87,17 @@ class PDFReaderActivity: AppCompatActivity(), DocumentListener { addOnAnnotationUpdatedListener(object: AnnotationProvider.OnAnnotationUpdatedListener { override fun onAnnotationCreated(annotation: Annotation) { - Log.i("anno", "The annotation was created. $annotation") + if (isNewAnnotation(annotation)) { + viewModel.createHighlight(annotation, params.item.id) + } } override fun onAnnotationUpdated(annotation: Annotation) { - Log.i("anno", "The annotation was updated. $annotation") + viewModel.updateHighlight(annotation) } override fun onAnnotationRemoved(annotation: Annotation) { - Log.i("anno", "The annotation was removed. $annotation") + viewModel.deleteHighlight(annotation) } override fun onAnnotationZOrderChanged( @@ -104,6 +111,14 @@ class PDFReaderActivity: AppCompatActivity(), DocumentListener { } } + // If created time is less than 2 seconds then we consider it a newly created annotation + private fun isNewAnnotation(annotation: Annotation): Boolean { + val currentTime = Calendar.getInstance().time.time + val createdTime = annotation.createdDate?.time ?: 0 + val duration = currentTime - createdTime + return duration < 2000 + } + override fun onDocumentLoaded(document: PdfDocument) { if (hasLoadedHighlights) return hasLoadedHighlights = true @@ -115,16 +130,7 @@ class PDFReaderActivity: AppCompatActivity(), DocumentListener { val params = viewModel.pdfReaderParamsLiveData.value params?.let { - for (highlight in it.articleContent.highlights) { - val highlightAnnotation = fragment - .document - ?.annotationProvider - ?.createAnnotationFromInstantJson(highlight.patch) - - highlightAnnotation?.let { - fragment.addAnnotationToPage(highlightAnnotation, true) - } - } + loadHighlights(it.articleContent.highlights) fragment.scrollTo( RectF(0f, 0f, 0f, 0f), @@ -135,6 +141,19 @@ class PDFReaderActivity: AppCompatActivity(), DocumentListener { } } + private fun loadHighlights(highlights: List) { + for (highlight in highlights) { + val highlightAnnotation = fragment + .document + ?.annotationProvider + ?.createAnnotationFromInstantJson(highlight.patch) + + highlightAnnotation?.let { + fragment.addAnnotationToPage(highlightAnnotation, true) + } + } + } + private fun createFragment(documentUri: Uri, configuration: PdfConfiguration): PdfFragment { val fragment = PdfFragment.newInstance(documentUri, configuration) supportFragmentManager.beginTransaction() diff --git a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReaderViewModel.kt b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReaderViewModel.kt index c673cfdd2..b1b374287 100644 --- a/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReaderViewModel.kt +++ b/android/Omnivore/app/src/main/java/app/omnivore/omnivore/ui/reader/PDFReaderViewModel.kt @@ -7,9 +7,14 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import app.omnivore.omnivore.DatastoreRepository +import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput +import app.omnivore.omnivore.models.Highlight import app.omnivore.omnivore.models.LinkedItem import app.omnivore.omnivore.networking.Networker +import app.omnivore.omnivore.networking.createHighlight +import app.omnivore.omnivore.networking.createWebHighlight import app.omnivore.omnivore.networking.linkedItem +import com.apollographql.apollo3.api.Optional import com.google.gson.Gson import com.pspdfkit.annotations.Annotation import com.pspdfkit.document.download.DownloadJob @@ -18,6 +23,7 @@ import com.pspdfkit.document.download.Progress import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import java.io.File +import java.util.* import javax.inject.Inject data class PDFReaderParams( @@ -74,4 +80,29 @@ class PDFReaderViewModel @Inject constructor( fun reset() { pdfReaderParamsLiveData.postValue(null) } + + fun createHighlight(annotation: Annotation, articleID: String) { + // TODO: Check for overlapping highlights + val createHighlightInput = CreateHighlightInput( + annotation = Optional.presentIfNotNull(null), + articleId = articleID, + id = UUID.randomUUID().toString(), + patch = annotation.toInstantJson(), + quote = annotation.contents ?: "", + shortId = UUID.randomUUID().toString().replace("-","").substring(0,8), + ) + + viewModelScope.launch { + val isHighlightSynced = networker.createHighlight(createHighlightInput) + Log.d("Network", "isHighlightSynced = $isHighlightSynced") + } + } + + fun updateHighlight(annotation: Annotation) { + + } + + fun deleteHighlight(annotation: Annotation) { + + } } 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 fa816a96f..c30c036ff 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 @@ -62,7 +62,7 @@ class WebReaderViewModel @Inject constructor( when (actionID) { "createHighlight" -> { viewModelScope.launch { - val isHighlightSynced = networker.createHighlight(jsonString) + val isHighlightSynced = networker.createWebHighlight(jsonString) Log.d("Network", "isHighlightSynced = $isHighlightSynced") } }