Improve PDF downloading on Android
This commit is contained in:
@ -17,8 +17,8 @@ android {
|
||||
applicationId "app.omnivore.omnivore"
|
||||
minSdk 26
|
||||
targetSdk 33
|
||||
versionCode 118
|
||||
versionName "0.0.118"
|
||||
versionCode 122
|
||||
versionName "0.0.122"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables {
|
||||
|
||||
@ -1,9 +1,15 @@
|
||||
package app.omnivore.omnivore.networking
|
||||
|
||||
import android.util.Log
|
||||
import app.omnivore.omnivore.graphql.generated.GetArticleQuery
|
||||
import app.omnivore.omnivore.graphql.generated.type.ContentReader
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItem
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import app.omnivore.omnivore.persistence.entities.Highlight
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
|
||||
data class SavedItemQueryResponse(
|
||||
val item: SavedItem?,
|
||||
@ -60,7 +66,18 @@ suspend fun Networker.savedItem(slug: String): SavedItemQueryResponse {
|
||||
)
|
||||
}
|
||||
|
||||
// TODO: handle errors
|
||||
var localPDFPath: String? = null
|
||||
if (article.articleFields.contentReader == ContentReader.PDF) {
|
||||
// download the PDF and save it locally
|
||||
// article.articleFields.url
|
||||
|
||||
val localFile = File.createTempFile("pdf-" + article.articleFields.id, ".pdf", )
|
||||
val url = URL(article.articleFields.url)
|
||||
Log.d("pdf", "creating local file: $localFile")
|
||||
|
||||
url.openStream().use { Files.copy(it, localFile.toPath(), StandardCopyOption.REPLACE_EXISTING) }
|
||||
localPDFPath = localFile.toPath().toString()
|
||||
}
|
||||
|
||||
val savedItem = SavedItem(
|
||||
savedItemId = article.articleFields.id,
|
||||
@ -82,7 +99,8 @@ suspend fun Networker.savedItem(slug: String): SavedItemQueryResponse {
|
||||
isArchived = article.articleFields.isArchived,
|
||||
contentReader = article.articleFields.contentReader.rawValue,
|
||||
content = article.articleFields.content,
|
||||
wordsCount = article.articleFields.wordsCount
|
||||
wordsCount = article.articleFields.wordsCount,
|
||||
localPDFPath = localPDFPath
|
||||
)
|
||||
|
||||
return SavedItemQueryResponse(item = savedItem, highlights, labels = savedItemLabels, state = article.articleFields.state?.rawValue ?: "")
|
||||
|
||||
@ -13,7 +13,7 @@ import app.omnivore.omnivore.persistence.entities.*
|
||||
SavedItemAndSavedItemLabelCrossRef::class,
|
||||
SavedItemAndHighlightCrossRef::class
|
||||
],
|
||||
version = 11
|
||||
version = 12
|
||||
)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun viewerDao(): ViewerDao
|
||||
|
||||
@ -40,7 +40,8 @@ data class SavedItem(
|
||||
@ColumnInfo(typeAffinity = ColumnInfo.BLOB) val pdfData: ByteArray? = null,
|
||||
var serverSyncStatus: Int = 0,
|
||||
val tempPDFURL: String? = null,
|
||||
val wordsCount: Int? = null
|
||||
val wordsCount: Int? = null,
|
||||
val localPDFPath: String? = null
|
||||
|
||||
// hasMany highlights
|
||||
// hasMany labels
|
||||
|
||||
@ -7,7 +7,7 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import app.omnivore.omnivore.DatastoreRepository
|
||||
import app.omnivore.omnivore.EventTracker
|
||||
import app.omnivore.omnivore.dataService.DataService
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateHighlightInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.MergeHighlightInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.UpdateHighlightInput
|
||||
@ -21,11 +21,16 @@ import com.pspdfkit.document.download.DownloadJob
|
||||
import com.pspdfkit.document.download.DownloadRequest
|
||||
import com.pspdfkit.document.download.Progress
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.lang.Double.max
|
||||
import java.lang.Double.min
|
||||
import java.lang.Exception
|
||||
import java.net.URLEncoder
|
||||
import java.nio.file.FileSystem
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -38,8 +43,8 @@ data class PDFReaderParams(
|
||||
@HiltViewModel
|
||||
class PDFReaderViewModel @Inject constructor(
|
||||
private val datastoreRepo: DatastoreRepository,
|
||||
private val networker: Networker,
|
||||
private val eventTracker: EventTracker,
|
||||
private val dataService: DataService,
|
||||
private val networker: Networker
|
||||
): ViewModel() {
|
||||
var annotationUnderNoteEdit: Annotation? = null
|
||||
val pdfReaderParamsLiveData = MutableLiveData<PDFReaderParams?>(null)
|
||||
@ -47,21 +52,51 @@ class PDFReaderViewModel @Inject constructor(
|
||||
|
||||
fun loadItem(slug: String, context: Context) {
|
||||
viewModelScope.launch {
|
||||
loadItemFromDB(slug)
|
||||
loadItemFromNetwork(slug, context)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadItemFromDB(slug: String) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val persistedItem = dataService.db.savedItemDao().getSavedItemWithLabelsAndHighlights(slug)
|
||||
persistedItem?.let { persistedItem ->
|
||||
persistedItem?.savedItem?.localPDF?.let { localPDF ->
|
||||
val localFile = File(localPDF)
|
||||
|
||||
if (localFile.exists()) {
|
||||
val articleContent = ArticleContent(
|
||||
title = persistedItem.savedItem.title,
|
||||
htmlContent = "",
|
||||
highlights = persistedItem.highlights,
|
||||
contentStatus = "SUCCEEDED",
|
||||
objectID = "",
|
||||
labelsJSONString = Gson().toJson(persistedItem.labels)
|
||||
)
|
||||
|
||||
pdfReaderParamsLiveData.postValue(
|
||||
PDFReaderParams(
|
||||
persistedItem.savedItem,
|
||||
articleContent,
|
||||
Uri.fromFile(localFile)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun loadItemFromNetwork(slug: String, context: Context) {
|
||||
withContext(Dispatchers.IO) {
|
||||
val articleQueryResult = networker.savedItem(slug)
|
||||
|
||||
val article = articleQueryResult.item ?: return@launch
|
||||
|
||||
val article = articleQueryResult.item ?: return@withContext
|
||||
val request = DownloadRequest.Builder(context)
|
||||
.uri(article.pageURLString)
|
||||
.build()
|
||||
|
||||
val job = DownloadJob.startDownload(request)
|
||||
|
||||
job.setProgressListener(object : DownloadJob.ProgressListenerAdapter() {
|
||||
override fun onProgress(progress: Progress) {
|
||||
// progressBar.setProgress((100f * progress.bytesReceived / progress.totalBytes).toInt())
|
||||
}
|
||||
|
||||
override fun onComplete(output: File) {
|
||||
val articleContent = ArticleContent(
|
||||
title = article.title,
|
||||
@ -72,22 +107,18 @@ class PDFReaderViewModel @Inject constructor(
|
||||
labelsJSONString = Gson().toJson(articleQueryResult.labels)
|
||||
)
|
||||
|
||||
val pdfReaderParams = PDFReaderParams(article, articleContent, Uri.fromFile(output))
|
||||
|
||||
eventTracker.track("link_read",
|
||||
com.posthog.android.Properties()
|
||||
.putValue("linkID", pdfReaderParams.item.savedItemId)
|
||||
.putValue("slug", pdfReaderParams.item.slug)
|
||||
.putValue("originalArticleURL", pdfReaderParams.item.pageURLString)
|
||||
.putValue("loaded_from", "network")
|
||||
)
|
||||
|
||||
currentReadingProgress = article.readingProgress
|
||||
pdfReaderParamsLiveData.postValue(pdfReaderParams)
|
||||
pdfReaderParamsLiveData.postValue(
|
||||
PDFReaderParams(
|
||||
article,
|
||||
articleContent,
|
||||
Uri.fromFile(output)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onError(exception: Throwable) {
|
||||
// handleDownloadError(exception)
|
||||
// handleDownloadError(exception)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ data class WebReaderContent(
|
||||
url: `${item.pageURLString}`,
|
||||
title: `${articleContent.title.replace("`", "\\`")}`,
|
||||
content: document.getElementById('_omnivore-htmlContent').innerHTML,
|
||||
originalArticleUrl: "${item.pageURLString}",
|
||||
originalArticleUrl: "${item.publisherURLString}",
|
||||
contentReader: "WEB",
|
||||
readingProgressPercent: ${item.readingProgress},
|
||||
readingProgressAnchorIndex: ${item.readingProgressAnchor},
|
||||
|
||||
Reference in New Issue
Block a user