* add a UI trigger for demo annotations * Implement internal link navigation * Simplify bottom padding logic in `EpubReaderScreen` for vertical scroll mode * Add support for Calibre metadata * Implement advanced library management with Room-backed collections, tags, and smart rules. * Display book series information in book details and remove tags from home screen * Implement zoom reset functionality in PDF viewer * Add a "Pages" thumbnail view to the PDF navigation drawer * Implement jump-back navigation in PDF viewer * MainViewModel: disable FolderSyncWorker, add log export, and enhance PDF position logging * Replace Gson with Kotlin Serialization in SmartCollectionEngine * Implement ONNX-based speech bubble detection * Implement speech bubble detection in PDF viewer * Implement "Smart Comic Zoom" feature for PDF manga/comic reading * Implement reader session persistence and restoration in `MainViewModel` * Add tap-to-turn page feature to PDF viewer * Improve book cache management and recovery * Refactor top overlay padding logic in `PdfViewerScreen` * Implement stylus eraser support in PDF reader * Refactor ReaderTextFormatPanel to use ModalBottomSheet and add new formatting controls * Introduce a customizable horizontal margin setting for the EPUB reader * Refine folder sync and metadata handling for better conflict resolution and stability. * Introduce user-adjustable image scaling for the EPUB reader * Use maxWidthPx as default width fallback for blocks * Improve cross-page text selection and header styling in the paginated reader * Refactor speech bubble detection and UI to support segmentation masks and interactive scaling * Improve speech bubble detection masking and rendering quality * Update ONNX speech bubble detector to use `.ort` model and optimize inference * Improve pagination accuracy * Implement hierarchical folder navigation for the library. * Refactor library item layout for improved space efficiency * Add support for browsing and downloading Google Fonts * Persist library landing state and add shelf search functionality * Fix base tts sample. * Move SpeechBubbleDetector to main source set and update ONNX dependency * Implement a "locate" feature and improve synchronization for TTS (Text-to-Speech) playback across EPUB and PDF readers. * Refine TTS synchronization and voice management in the EPUB reader * Adjust OCR checks for OSS flavor and optimize external dictionary intent flags * Add "Locate" button to PDF drawer's pages tab and move the page number to bottom right of thumbnail * fix various crashes * Refactor SpeechBubbleDetector into product flavors * Implement speech bubble detection caching and background prefetching * Implement on-demand download for Bubble Zoom ML model * Add smooth animation for PDF speech bubble expansion * fixes #252 * hide Google Fonts option, in FontsScreen, for offline variant * Bump version to 1.0.46(46)
81 lines
2.9 KiB
Kotlin
81 lines
2.9 KiB
Kotlin
package com.aryan.reader.data
|
|
|
|
import kotlinx.serialization.Serializable
|
|
import kotlinx.serialization.encodeToString
|
|
import kotlinx.serialization.json.Json
|
|
|
|
@Serializable
|
|
enum class SmartField { TITLE, AUTHOR, PROGRESS, FILE_TYPE, FOLDER, TAG }
|
|
@Serializable
|
|
enum class SmartOperator { EQUALS, CONTAINS, GREATER_THAN, LESS_THAN }
|
|
|
|
@Serializable
|
|
data class SmartRule(
|
|
val field: SmartField,
|
|
val operator: SmartOperator,
|
|
val value: String
|
|
)
|
|
|
|
@Serializable
|
|
data class SmartCollectionDefinition(
|
|
val matchAll: Boolean = true,
|
|
val rules: List<SmartRule> = emptyList()
|
|
)
|
|
|
|
object SmartCollectionEngine {
|
|
private val json = Json {
|
|
encodeDefaults = true
|
|
ignoreUnknownKeys = true
|
|
}
|
|
|
|
fun toJson(definition: SmartCollectionDefinition): String = json.encodeToString(definition)
|
|
|
|
fun fromJson(json: String?): SmartCollectionDefinition? {
|
|
if (json.isNullOrBlank()) return null
|
|
return try {
|
|
this.json.decodeFromString<SmartCollectionDefinition>(json)
|
|
} catch (_: Exception) { null }
|
|
}
|
|
|
|
fun evaluate(book: RecentFileItem, definition: SmartCollectionDefinition): Boolean {
|
|
if (definition.rules.isEmpty()) return false
|
|
|
|
val results = definition.rules.map { rule ->
|
|
when (rule.field) {
|
|
SmartField.TITLE -> evaluateString(book.title ?: book.displayName, rule)
|
|
SmartField.AUTHOR -> evaluateString(book.author ?: "", rule)
|
|
SmartField.FILE_TYPE -> evaluateString(book.type.name, rule)
|
|
SmartField.FOLDER -> evaluateString(book.sourceFolderUri ?: "", rule)
|
|
SmartField.TAG -> evaluateTags(book.tags.map { it.name }, rule)
|
|
SmartField.PROGRESS -> evaluateNumber(book.progressPercentage ?: 0f, rule)
|
|
}
|
|
}
|
|
return if (definition.matchAll) results.all { it } else results.any { it }
|
|
}
|
|
|
|
private fun evaluateString(target: String, rule: SmartRule): Boolean {
|
|
return when (rule.operator) {
|
|
SmartOperator.EQUALS -> target.equals(rule.value, ignoreCase = true)
|
|
SmartOperator.CONTAINS -> target.contains(rule.value, ignoreCase = true)
|
|
else -> false
|
|
}
|
|
}
|
|
|
|
private fun evaluateNumber(target: Float, rule: SmartRule): Boolean {
|
|
val ruleValue = rule.value.toFloatOrNull() ?: return false
|
|
return when (rule.operator) {
|
|
SmartOperator.EQUALS -> target == ruleValue
|
|
SmartOperator.GREATER_THAN -> target > ruleValue
|
|
SmartOperator.LESS_THAN -> target < ruleValue
|
|
else -> false
|
|
}
|
|
}
|
|
|
|
private fun evaluateTags(tags: List<String>, rule: SmartRule): Boolean {
|
|
return when (rule.operator) {
|
|
SmartOperator.EQUALS -> tags.any { it.equals(rule.value, ignoreCase = true) }
|
|
SmartOperator.CONTAINS -> tags.any { it.contains(rule.value, ignoreCase = true) }
|
|
else -> false
|
|
}
|
|
}
|
|
}
|