From 67172058899873d094ecb695c3f1850b847587c8 Mon Sep 17 00:00:00 2001 From: Dima Date: Tue, 7 Jan 2025 02:54:11 +0900 Subject: [PATCH] =?UTF-8?q?Changing=20implementation=20of=20the=20fix=20fo?= =?UTF-8?q?r=20=E2=80=9Cwidth=20and=20height=20must=20be=20>=200=E2=80=9D?= =?UTF-8?q?=20bug.=20Also=20adding=20INK=20annotation=20type=20to=20the=20?= =?UTF-8?q?list=20of=20annotations=20we=20check=20for=20zero=20dimensions.?= =?UTF-8?q?=20#206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upping versionCode to 128 --- .../zotero/android/architecture/Defaults.kt | 10 --- ...notationsWithZeroWidthOrHeightDbRequest.kt | 36 ----------- .../android/pdf/reader/PdfReaderViewModel.kt | 64 ++++++++++++++++--- .../android/sync/AnnotationConverter.kt | 25 +++++--- .../zotero/android/sync/UserControllers.kt | 9 --- buildSrc/src/main/kotlin/BuildConfig.kt | 2 +- 6 files changed, 72 insertions(+), 74 deletions(-) delete mode 100644 app/src/main/java/org/zotero/android/database/requests/FixSquareAnnotationsWithZeroWidthOrHeightDbRequest.kt diff --git a/app/src/main/java/org/zotero/android/architecture/Defaults.kt b/app/src/main/java/org/zotero/android/architecture/Defaults.kt index 7cbbfc64..b032c7c2 100644 --- a/app/src/main/java/org/zotero/android/architecture/Defaults.kt +++ b/app/src/main/java/org/zotero/android/architecture/Defaults.kt @@ -58,8 +58,6 @@ open class Defaults @Inject constructor( private val webDavScheme = "webDavScheme" private val webDavPassword = "webDavPassword" - private val needsZeroWidthOrHeightAnnotationsFix = "needsZeroWidthOrHeightAnnotationsFix2" - private val sharedPreferences: SharedPreferences by lazy { context.getSharedPreferences( sharedPrefsFile, @@ -397,14 +395,6 @@ open class Defaults @Inject constructor( return sharedPreferences.getInt(performFullSyncGuardKey, 1) } - fun needsZeroWidthOrHeightAnnotationsFix(): Boolean { - return sharedPreferences.getBoolean(needsZeroWidthOrHeightAnnotationsFix, true) - } - - fun setNeedsZeroWidthOrHeightAnnotationsFix(value: Boolean) { - sharedPreferences.edit { putBoolean(needsZeroWidthOrHeightAnnotationsFix, value) } - } - fun reset() { setUsername("") setDisplayName("") diff --git a/app/src/main/java/org/zotero/android/database/requests/FixSquareAnnotationsWithZeroWidthOrHeightDbRequest.kt b/app/src/main/java/org/zotero/android/database/requests/FixSquareAnnotationsWithZeroWidthOrHeightDbRequest.kt deleted file mode 100644 index 3f02c501..00000000 --- a/app/src/main/java/org/zotero/android/database/requests/FixSquareAnnotationsWithZeroWidthOrHeightDbRequest.kt +++ /dev/null @@ -1,36 +0,0 @@ -package org.zotero.android.database.requests - -import io.realm.Realm -import io.realm.kotlin.where -import org.zotero.android.database.DbRequest -import org.zotero.android.database.objects.AnnotationType -import org.zotero.android.database.objects.ItemTypes -import org.zotero.android.database.objects.RItem - -class FixSquareAnnotationsWithZeroWidthOrHeightDbRequest : DbRequest { - override val needsWrite: Boolean - get() = true - - override fun process(database: Realm) { - val targetTypes = listOf(AnnotationType.image.name) - val results = database.where() - .item(type = ItemTypes.annotation) - .deleted(false) - .`in`("annotationType", targetTypes.toTypedArray()) - .findAll() - - for (rItem in results) { - val rect = rItem.rects.getOrNull(0) ?: continue - val libraryId = rItem.libraryId ?: continue - val width = rect.maxX - rect.minX - val height = rect.maxY - rect.minY - if (width == 0.0 || height == 0.0) { - MarkObjectsAsDeletedDbRequest( - clazz = RItem::class, - keys = listOf(rItem.key), - libraryId = libraryId - ).process(database) - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt index 22d62323..cc2e6064 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt @@ -845,12 +845,28 @@ class PdfReaderViewModel @Inject constructor( update( document = this.document, - zoteroAnnotations = dbToPdfAnnotations, + zoteroAnnotations = dbToPdfAnnotations.map { it.third }, key = key, libraryId = library.identifier, isDark = viewState.isDark ) - for (annotation in dbToPdfAnnotations) { + + val cleanedDbToPdfAnnotations = dbToPdfAnnotations.mapNotNull { triple -> + val libraryId = triple.first + val rItemKey = triple.second + val annotation = triple.third + if (wasAnnotationsWithZeroSizeRemoved( + libraryId = libraryId, + rItemKey = rItemKey, + annotation = annotation + ) + ) { + return@mapNotNull null + } + annotation + } + + for (annotation in cleanedDbToPdfAnnotations) { annotationPreviewManager.store( rawDocument = this.rawDocument, annotation = annotation, @@ -916,12 +932,8 @@ class PdfReaderViewModel @Inject constructor( onAnnotationUpdatedListener = object : AnnotationProvider.OnAnnotationUpdatedListener { override fun onAnnotationCreated(annotation: Annotation) { - //Don't allow Square Annotations with zero width or height from being added. - val annotationRect = annotation.boundingBox - val width = (annotationRect.right - annotationRect.left).toInt() - val height = (annotationRect.top - annotationRect.bottom).toInt() - if (annotation.type == AnnotationType.SQUARE && (width == 0 || height == 0)) { - Timber.w("PdfReaderViewModel: Prevented an annotation of type ${annotation.type} from being created with width=$width and height=$height") + if (isAnnotationZeroSize(annotation)) { + Timber.w("PdfReaderViewModel: Prevented an annotation of type ${annotation.type} from being created due to zero dimensions") this@PdfReaderViewModel.document.annotationProvider.removeAnnotationFromPage( annotation ) @@ -955,6 +967,42 @@ class PdfReaderViewModel @Inject constructor( pdfFragment.addOnAnnotationUpdatedListener(onAnnotationUpdatedListener!!) } + private fun wasAnnotationsWithZeroSizeRemoved( + libraryId: LibraryIdentifier, + rItemKey: String, + annotation: Annotation + ): Boolean { + if (isAnnotationZeroSize(annotation)) { + this@PdfReaderViewModel.document.annotationProvider.removeAnnotationFromPage( + annotation + ) + dbWrapperMain.realmDbStorage.perform( + MarkObjectsAsDeletedDbRequest( + clazz = RItem::class, + keys = listOf(rItemKey), + libraryId = libraryId + ) + ) + return true + } + return false + } + + private fun isAnnotationZeroSize(annotation: Annotation): Boolean { + val annotationRect = annotation.boundingBox + val width = (annotationRect.right - annotationRect.left).toInt() + val height = (annotationRect.top - annotationRect.bottom).toInt() + if (listOf( + AnnotationType.SQUARE, + AnnotationType.INK + ).contains(annotation.type) && (width == 0 || height == 0) + ) { + Timber.w("PdfReaderViewModel: Found an annotation of type ${annotation.type} having zero dimensions width=$width and height=$height") + return true + } + return false + } + private fun change(annotation: Annotation, changes: List) { if (changes.isEmpty()) { return diff --git a/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt b/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt index 41822a45..61773541 100644 --- a/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt +++ b/app/src/main/java/org/zotero/android/sync/AnnotationConverter.kt @@ -50,18 +50,23 @@ class AnnotationConverter { username: String, boundingBoxConverter: AnnotationBoundingBoxConverter, isDarkMode: Boolean, - ): List = withContext(Dispatchers.IO) { + ): List> = withContext(Dispatchers.IO) { items.mapNotNull { item -> val annotation = PDFDatabaseAnnotation.init(item) ?: return@mapNotNull null - annotation( - zoteroAnnotation = annotation, - type = type, - currentUserId = currentUserId, - library = library, - displayName = displayName, - username = username, - boundingBoxConverter = boundingBoxConverter, - isDarkMode = isDarkMode + val libraryId = item.libraryId ?: return@mapNotNull null + Triple( + libraryId, + item.key, + annotation( + zoteroAnnotation = annotation, + type = type, + currentUserId = currentUserId, + library = library, + displayName = displayName, + username = username, + boundingBoxConverter = boundingBoxConverter, + isDarkMode = isDarkMode + ) ) } } diff --git a/app/src/main/java/org/zotero/android/sync/UserControllers.kt b/app/src/main/java/org/zotero/android/sync/UserControllers.kt index 39c4d405..21466ebd 100644 --- a/app/src/main/java/org/zotero/android/sync/UserControllers.kt +++ b/app/src/main/java/org/zotero/android/sync/UserControllers.kt @@ -14,7 +14,6 @@ import org.zotero.android.architecture.coroutines.Dispatchers import org.zotero.android.attachmentdownloader.AttachmentDownloader import org.zotero.android.database.DbWrapperMain import org.zotero.android.database.requests.CleanupUnusedTags -import org.zotero.android.database.requests.FixSquareAnnotationsWithZeroWidthOrHeightDbRequest import org.zotero.android.files.FileStore import org.zotero.android.websocket.ChangeWsResponse import timber.log.Timber @@ -58,14 +57,6 @@ class UserControllers @Inject constructor( dbWrapperMain.realmDbStorage.perform(coordinatorAction = { coordinator -> isFirstLaunch = coordinator.perform(InitializeCustomLibrariesDbRequest()) coordinator.perform(CleanupUnusedTags()) - - if (defaults.needsZeroWidthOrHeightAnnotationsFix()) { - fileStore.annotationPreviews.deleteRecursively() - fileStore.pageThumbnails.deleteRecursively() - coordinator.perform(FixSquareAnnotationsWithZeroWidthOrHeightDbRequest()) - defaults.setNeedsZeroWidthOrHeightAnnotationsFix(false) - } - coordinator.invalidate() }) } diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt index 06200256..6a55cb7a 100644 --- a/buildSrc/src/main/kotlin/BuildConfig.kt +++ b/buildSrc/src/main/kotlin/BuildConfig.kt @@ -4,7 +4,7 @@ object BuildConfig { const val compileSdkVersion = 34 const val targetSdk = 34 - val versionCode = 127 // Must be updated on every build + val versionCode = 128 // Must be updated on every build val version = Version( major = 1, minor = 0,