diff --git a/app/src/main/java/com/kafka/user/initializer/ReaderProgressInitializer.kt b/app/src/main/java/com/kafka/user/initializer/ReaderProgressInitializer.kt index 50f931a49..7f013a595 100644 --- a/app/src/main/java/com/kafka/user/initializer/ReaderProgressInitializer.kt +++ b/app/src/main/java/com/kafka/user/initializer/ReaderProgressInitializer.kt @@ -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 @@ -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 @@ -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, @@ -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)) @@ -66,13 +61,11 @@ class ReaderProgressInitializer @Inject constructor( } class RecentTextItemMapper @Inject constructor() { - fun map(download: Download, pages: List, 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() ) } diff --git a/data/database/src/main/java/com/kafka/data/dao/FileDao.kt b/data/database/src/main/java/com/kafka/data/dao/FileDao.kt index d10cb3a86..7a4125619 100644 --- a/data/database/src/main/java/com/kafka/data/dao/FileDao.kt +++ b/data/database/src/main/java/com/kafka/data/dao/FileDao.kt @@ -12,6 +12,9 @@ import kotlinx.coroutines.flow.Flow @Dao abstract class FileDao : EntityDao { + @Query("select * from File where fileId = :fileId") + abstract fun observe(fileId: String): Flow + @Query("select * from File where itemId = :itemId ORDER BY name") abstract fun observeByItemId(itemId: String): Flow> diff --git a/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt b/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt index d202914c0..b089151a7 100644 --- a/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt +++ b/data/database/src/main/java/com/kafka/data/entities/RecentItem.kt @@ -52,7 +52,7 @@ data class RecentTextItem( val currentPage: Int, // starts at 1 val localUri: String, val type: Type, - val pages: List, + val pages: List = emptyList(), ) : BaseEntity { enum class Type { PDF, TXT; diff --git a/domain/src/main/java/org/kafka/domain/interactors/GetReaderState.kt b/domain/src/main/java/org/kafka/domain/interactors/GetReaderState.kt index c269b6e2f..36125bbf8 100644 --- a/domain/src/main/java/org/kafka/domain/interactors/GetReaderState.kt +++ b/domain/src/main/java/org/kafka/domain/interactors/GetReaderState.kt @@ -52,8 +52,7 @@ class GetReaderState @Inject constructor( fileId = fileId, currentPage = currentPage, localUri = "", - type = RecentTextItem.Type.PDF, - pages = emptyList() + type = RecentTextItem.Type.PDF ) } diff --git a/domain/src/main/java/org/kafka/domain/observers/ObserveTxtPages.kt b/domain/src/main/java/org/kafka/domain/observers/ObserveTxtPages.kt new file mode 100644 index 000000000..11f7b9225 --- /dev/null +++ b/domain/src/main/java/org/kafka/domain/observers/ObserveTxtPages.kt @@ -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>() { + + override fun createObservable(params: Params): Flow> { + 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) +} diff --git a/ui/reader/src/main/java/com/kafka/reader/text/TextReader.kt b/ui/reader/src/main/java/com/kafka/reader/text/TextReader.kt index 928004eec..30efe5c07 100644 --- a/ui/reader/src/main/java/com/kafka/reader/text/TextReader.kt +++ b/ui/reader/src/main/java/com/kafka/reader/text/TextReader.kt @@ -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 @@ -42,15 +41,21 @@ 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 + ) } } @@ -58,7 +63,7 @@ internal fun TextReader( private fun TextReader( modifier: Modifier, viewModel: TextReaderViewModel, - recentTextItem: RecentTextItem, + pages: List, currentPage: Int = 0, lazyListState: LazyListState = rememberLazyListState() ) { @@ -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() } diff --git a/ui/reader/src/main/java/com/kafka/reader/text/TextReaderViewModel.kt b/ui/reader/src/main/java/com/kafka/reader/text/TextReaderViewModel.kt index a5758ac11..98fe6f94b 100644 --- a/ui/reader/src/main/java/com/kafka/reader/text/TextReaderViewModel.kt +++ b/ui/reader/src/main/java/com/kafka/reader/text/TextReaderViewModel.kt @@ -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 @@ -14,12 +14,14 @@ 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) @@ -27,18 +29,16 @@ class TextReaderViewModel @Inject constructor( 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 } @@ -49,3 +49,9 @@ class TextReaderViewModel @Inject constructor( } } } + +data class TxtReaderViewState( + val recentItem: RecentTextItem? = null, + val pages: List = emptyList(), + val message: org.kafka.common.snackbar.UiMessage? = null, +)