Skip to content

Commit

Permalink
Remove txt pages from the database and only save the URI - text conte…
Browse files Browse the repository at this point in the history
…nt can be extracted from URI by the reader. This fixes crashes where database would not be able to handle large text pages;
  • Loading branch information
vipulyaara committed Apr 23, 2024
1 parent e971cce commit 8ab7c7e
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 29 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import com.kafka.data.dao.RecentTextDao
import com.kafka.data.entities.File
import com.kafka.data.entities.RecentTextItem
import com.kafka.data.entities.isText
import com.kafka.data.entities.isTxt
import com.tonyodev.fetch2.Download
import com.tonyodev.fetch2.Fetch
import com.tonyodev.fetch2.Status
Expand All @@ -18,7 +17,6 @@ import org.kafka.base.AppInitializer
import org.kafka.base.CoroutineDispatchers
import org.kafka.base.ProcessLifetime
import org.kafka.base.errorLog
import org.kafka.domain.interactors.ReadTextFromUri
import tm.alashow.datmusic.downloader.manager.createFetchListener
import javax.inject.Inject

Expand All @@ -28,7 +26,6 @@ import javax.inject.Inject
class ReaderProgressInitializer @Inject constructor(
private val fetch: Fetch,
@ProcessLifetime private val coroutineScope: CoroutineScope,
private val readTextFromUri: ReadTextFromUri,
private val downloadRequestsDao: DownloadRequestsDao,
private val fileDao: FileDao,
private val recentTextItemMapper: RecentTextItemMapper,
Expand All @@ -54,9 +51,7 @@ class ReaderProgressInitializer @Inject constructor(
}

if (file != null && file.isText()) {
val pages = if (file.isTxt()) readTextFromUri(download.fileUri)
.getOrElse { emptyList() } else emptyList()
val textFile = recentTextItemMapper.map(download, pages, file)
val textFile = recentTextItemMapper.map(download, file)
val currentPage = recentTextDao.getOrNull(file.fileId)?.currentPage ?: 1

recentTextDao.insert(textFile.copy(currentPage = currentPage))
Expand All @@ -66,13 +61,11 @@ class ReaderProgressInitializer @Inject constructor(
}

class RecentTextItemMapper @Inject constructor() {
fun map(download: Download, pages: List<String>, file: File): RecentTextItem {
val filePages = pages.mapIndexed { index, s -> RecentTextItem.Page(index + 1, s) }
fun map(download: Download, file: File): RecentTextItem {
return RecentTextItem(
fileId = file.fileId,
currentPage = 1,
type = RecentTextItem.Type.fromString(file.extension),
pages = filePages,
localUri = download.fileUri.toString()
)
}
Expand Down
3 changes: 3 additions & 0 deletions data/database/src/main/java/com/kafka/data/dao/FileDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ import kotlinx.coroutines.flow.Flow
@Dao
abstract class FileDao : EntityDao<File> {

@Query("select * from File where fileId = :fileId")
abstract fun observe(fileId: String): Flow<File?>

@Query("select * from File where itemId = :itemId ORDER BY name")
abstract fun observeByItemId(itemId: String): Flow<List<File>>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ data class RecentTextItem(
val currentPage: Int, // starts at 1
val localUri: String,
val type: Type,
val pages: List<Page>,
val pages: List<Page> = emptyList(),
) : BaseEntity {
enum class Type {
PDF, TXT;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ class GetReaderState @Inject constructor(
fileId = fileId,
currentPage = currentPage,
localUri = "",
type = RecentTextItem.Type.PDF,
pages = emptyList()
type = RecentTextItem.Type.PDF
)
}

Expand Down
43 changes: 43 additions & 0 deletions domain/src/main/java/org/kafka/domain/observers/ObserveTxtPages.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.kafka.domain.observers

import androidx.core.net.toUri
import com.kafka.data.dao.FileDao
import com.kafka.data.dao.RecentTextDao
import com.kafka.data.entities.RecentTextItem
import com.kafka.data.entities.isTxt
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import org.kafka.base.domain.SubjectInteractor
import org.kafka.domain.interactors.ReadTextFromUri
import javax.inject.Inject

/**
* Observe recent text file and extract pages using the local uri.
* */
class ObserveTxtPages @Inject constructor(
private val fileDao: FileDao,
private val recentTextDao: RecentTextDao,
private val readTextFromUri: ReadTextFromUri
) : SubjectInteractor<ObserveTxtPages.Params, List<RecentTextItem.Page>>() {

override fun createObservable(params: Params): Flow<List<RecentTextItem.Page>> {
return combine(
recentTextDao.observe(params.fileId),
fileDao.observe(params.fileId)
) { recentText, file ->
if (file != null) {
val pages = if (file.isTxt()) {
readTextFromUri(recentText.localUri.toUri()).getOrElse { emptyList() }
} else {
emptyList()
}

pages.mapIndexed { index, s -> RecentTextItem.Page(index + 1, s) }
} else {
emptyList()
}
}
}

data class Params(val fileId: String)
}
19 changes: 12 additions & 7 deletions ui/reader/src/main/java/com/kafka/reader/text/TextReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.kafka.data.entities.RecentItem
import com.kafka.data.entities.RecentTextItem
import com.kafka.reader.controls.GoToPage
import kotlinx.coroutines.launch
Expand All @@ -42,23 +41,29 @@ internal fun TextReader(
viewModel.observeTextFile(fileId)
}

viewState.recentItem?.let {
val lazyListState = rememberLazyListState(it.currentPage)
viewState.recentItem?.let { recentTextItem ->
val lazyListState = rememberLazyListState(recentTextItem.currentPage)
val currentPage by remember { derivedStateOf { lazyListState.firstVisibleItemIndex } }

LaunchedEffect(it, currentPage) {
LaunchedEffect(recentTextItem, currentPage) {
viewModel.onPageChanged(fileId, currentPage)
}

TextReader(modifier, viewModel, it, currentPage, lazyListState)
TextReader(
modifier = modifier,
viewModel = viewModel,
pages = viewState.pages,
currentPage = currentPage,
lazyListState = lazyListState
)
}
}

@Composable
private fun TextReader(
modifier: Modifier,
viewModel: TextReaderViewModel,
recentTextItem: RecentTextItem,
pages: List<RecentTextItem.Page>,
currentPage: Int = 0,
lazyListState: LazyListState = rememberLazyListState()
) {
Expand All @@ -68,7 +73,7 @@ private fun TextReader(

Box(modifier = Modifier.fillMaxSize()) {
LazyColumn(contentPadding = scaffoldPadding, state = lazyListState) {
items(recentTextItem.pages, key = { it.index }) { page ->
items(pages, key = { it.index }) { page ->
Page(
page = page,
modifier = Modifier.simpleClickable { viewModel.toggleControls() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.kafka.reader.pdf.PdfReaderViewState
import com.kafka.data.entities.RecentTextItem
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.combine
Expand All @@ -14,31 +14,31 @@ import org.kafka.base.extensions.stateInDefault
import org.kafka.common.UiMessageManager
import org.kafka.domain.interactors.UpdateCurrentPage
import org.kafka.domain.observers.ObserveRecentTextItem
import org.kafka.domain.observers.ObserveTxtPages
import javax.inject.Inject

@HiltViewModel
class TextReaderViewModel @Inject constructor(
private val observeTextFile: ObserveRecentTextItem,
private val updateCurrentPage: UpdateCurrentPage,
private val observeTxtPages: ObserveTxtPages
) : ViewModel() {
private val uiMessageManager = UiMessageManager()
var showControls by mutableStateOf(false)

val readerState = combine(
observeTextFile.flow,
uiMessageManager.message,
) { textFile, message ->
PdfReaderViewState(recentItem = textFile, message = message)
}.stateInDefault(
scope = viewModelScope,
initialValue = PdfReaderViewState(),
)
observeTxtPages.flow
) { textFile, message, pages ->
TxtReaderViewState(recentItem = textFile, pages = pages, message = message)
}.stateInDefault(scope = viewModelScope, initialValue = TxtReaderViewState())

fun observeTextFile(fileId: String) {
viewModelScope.launch {
observeTextFile.invoke(fileId)
}
observeTextFile.invoke(fileId)
observeTxtPages(ObserveTxtPages.Params(fileId))
}

fun toggleControls() {
showControls = !showControls
}
Expand All @@ -49,3 +49,9 @@ class TextReaderViewModel @Inject constructor(
}
}
}

data class TxtReaderViewState(
val recentItem: RecentTextItem? = null,
val pages: List<RecentTextItem.Page> = emptyList(),
val message: org.kafka.common.snackbar.UiMessage? = null,
)

0 comments on commit 8ab7c7e

Please sign in to comment.