Refactored the code for saving the history in room database.

This commit is contained in:
MohitMaliFtechiz 2024-05-30 12:21:56 +05:30
parent e32e3e6371
commit c2446d27c4
15 changed files with 71 additions and 25 deletions

View File

@ -355,4 +355,6 @@ object Libs {
const val roomKtx = "androidx.room:room-ktx:" + Versions.roomVersion const val roomKtx = "androidx.room:room-ktx:" + Versions.roomVersion
const val roomCompiler = "androidx.room:room-compiler:" + Versions.roomVersion const val roomCompiler = "androidx.room:room-compiler:" + Versions.roomVersion
const val roomRuntime = "androidx.room:room-runtime:" + Versions.roomVersion
} }

View File

@ -207,6 +207,8 @@ class AllProjectConfigurer {
implementation(Libs.preference_ktx) implementation(Libs.preference_ktx)
implementation(Libs.material_show_case_view) implementation(Libs.material_show_case_view)
implementation(Libs.roomKtx) implementation(Libs.roomKtx)
annotationProcessor(Libs.roomCompiler)
implementation(Libs.roomRuntime)
kapt(Libs.roomCompiler) kapt(Libs.roomCompiler)
} }
} }

View File

@ -54,5 +54,8 @@ internal fun DependencyHandlerScope.testImplementation(dependency: String) =
internal fun DependencyHandlerScope.implementation(dependency: String) = internal fun DependencyHandlerScope.implementation(dependency: String) =
addDependency("implementation", dependency) addDependency("implementation", dependency)
internal fun DependencyHandlerScope.annotationProcessor(dependency: String) =
addDependency("annotationProcessor", dependency)
private fun DependencyHandlerScope.addDependency(configurationName: String, dependency: String) = private fun DependencyHandlerScope.addDependency(configurationName: String, dependency: String) =
add(configurationName, dependency) add(configurationName, dependency)

View File

@ -23,6 +23,9 @@ import androidx.room.Database
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.TypeConverters import androidx.room.TypeConverters
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDaoCoverts import org.kiwix.kiwixmobile.core.dao.HistoryRoomDaoCoverts
import org.kiwix.kiwixmobile.core.dao.RecentSearchRoomDao import org.kiwix.kiwixmobile.core.dao.RecentSearchRoomDao
import org.kiwix.kiwixmobile.core.dao.entities.HistoryRoomEntity import org.kiwix.kiwixmobile.core.dao.entities.HistoryRoomEntity
@ -33,6 +36,7 @@ import org.kiwix.kiwixmobile.core.dao.entities.RecentSearchRoomEntity
@TypeConverters(HistoryRoomDaoCoverts::class) @TypeConverters(HistoryRoomDaoCoverts::class)
abstract class KiwixRoomDatabase : RoomDatabase() { abstract class KiwixRoomDatabase : RoomDatabase() {
abstract fun recentSearchRoomDao(): RecentSearchRoomDao abstract fun recentSearchRoomDao(): RecentSearchRoomDao
abstract fun historyRoomDao(): HistoryRoomDao
companion object { companion object {
private var db: KiwixRoomDatabase? = null private var db: KiwixRoomDatabase? = null
@ -42,10 +46,16 @@ abstract class KiwixRoomDatabase : RoomDatabase() {
?: Room.databaseBuilder(context, KiwixRoomDatabase::class.java, "KiwixRoom.db") ?: Room.databaseBuilder(context, KiwixRoomDatabase::class.java, "KiwixRoom.db")
// We have already database name called kiwix.db in order to avoid complexity we named // We have already database name called kiwix.db in order to avoid complexity we named
// as kiwixRoom.db // as kiwixRoom.db
// .addMigrations(MIGRATION_1_2)
.build() .build()
} }
} }
private val MIGRATION_1_2: Migration = object : Migration(1, 2) {
override fun migrate(database: SupportSQLiteDatabase) {
}
}
fun destroyInstance() { fun destroyInstance() {
db = null db = null
} }

View File

@ -22,7 +22,7 @@ import io.reactivex.Completable
import io.reactivex.Flowable import io.reactivex.Flowable
import io.reactivex.Scheduler import io.reactivex.Scheduler
import io.reactivex.Single import io.reactivex.Single
import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks
import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao import org.kiwix.kiwixmobile.core.dao.NewLanguagesDao
@ -54,7 +54,7 @@ class Repository @Inject internal constructor(
@param:MainThread private val mainThread: Scheduler, @param:MainThread private val mainThread: Scheduler,
private val bookDao: NewBookDao, private val bookDao: NewBookDao,
private val libkiwixBookmarks: LibkiwixBookmarks, private val libkiwixBookmarks: LibkiwixBookmarks,
private val historyDao: HistoryDao, private val historyRoomDao: HistoryRoomDao,
private val notesDao: NewNoteDao, private val notesDao: NewNoteDao,
private val languageDao: NewLanguagesDao, private val languageDao: NewLanguagesDao,
private val recentSearchRoomDao: RecentSearchRoomDao, private val recentSearchRoomDao: RecentSearchRoomDao,
@ -90,17 +90,17 @@ class Repository @Inject internal constructor(
.subscribeOn(io) .subscribeOn(io)
override fun saveHistory(history: HistoryItem) = override fun saveHistory(history: HistoryItem) =
Completable.fromAction { historyDao.saveHistory(history) } Completable.fromAction { historyRoomDao.saveHistory(history) }
.subscribeOn(io) .subscribeOn(io)
override fun deleteHistory(historyList: List<HistoryListItem>) = override fun deleteHistory(historyList: List<HistoryListItem>) =
Completable.fromAction { Completable.fromAction {
historyDao.deleteHistory(historyList.filterIsInstance(HistoryItem::class.java)) historyRoomDao.deleteHistory(historyList.filterIsInstance(HistoryItem::class.java))
} }
.subscribeOn(io) .subscribeOn(io)
override fun clearHistory() = Completable.fromAction { override fun clearHistory() = Completable.fromAction {
historyDao.deleteAllHistory() historyRoomDao.deleteAllHistory()
recentSearchRoomDao.deleteSearchHistory() recentSearchRoomDao.deleteSearchHistory()
}.subscribeOn(io) }.subscribeOn(io)

View File

@ -29,6 +29,7 @@ import org.kiwix.kiwixmobile.core.CoreApp
import org.kiwix.kiwixmobile.core.StorageObserver import org.kiwix.kiwixmobile.core.StorageObserver
import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao import org.kiwix.kiwixmobile.core.dao.FetchDownloadDao
import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks import org.kiwix.kiwixmobile.core.dao.LibkiwixBookmarks
import org.kiwix.kiwixmobile.core.dao.NewBookDao import org.kiwix.kiwixmobile.core.dao.NewBookDao
import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao import org.kiwix.kiwixmobile.core.dao.NewBookmarksDao
@ -100,6 +101,7 @@ interface CoreComponent {
fun objectBoxToLibkiwixMigrator(): ObjectBoxToLibkiwixMigrator fun objectBoxToLibkiwixMigrator(): ObjectBoxToLibkiwixMigrator
fun libkiwixBookmarks(): LibkiwixBookmarks fun libkiwixBookmarks(): LibkiwixBookmarks
fun recentSearchRoomDao(): RecentSearchRoomDao fun recentSearchRoomDao(): RecentSearchRoomDao
fun historyRoomDao(): HistoryRoomDao
fun objectBoxToRoomMigrator(): ObjectBoxToRoomMigrator fun objectBoxToRoomMigrator(): ObjectBoxToRoomMigrator
fun context(): Context fun context(): Context
fun downloader(): Downloader fun downloader(): Downloader

View File

@ -88,4 +88,8 @@ open class DatabaseModule {
@Singleton @Singleton
@Provides @Provides
fun provideNewRecentSearchRoomDao(db: KiwixRoomDatabase) = db.recentSearchRoomDao() fun provideNewRecentSearchRoomDao(db: KiwixRoomDatabase) = db.recentSearchRoomDao()
@Provides
@Singleton
fun provideHistoryDao(db: KiwixRoomDatabase) = db.historyRoomDao()
} }

View File

@ -65,7 +65,7 @@ class BookmarkViewModel @Inject constructor(
state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) }) state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })
override fun createDeletePageDialogEffect(state: BookmarkState) = override fun createDeletePageDialogEffect(state: BookmarkState) =
ShowDeleteBookmarksDialog(effects, state, pageDao) ShowDeleteBookmarksDialog(effects, state, basePageDao)
override fun copyWithNewItems( override fun copyWithNewItems(
state: BookmarkState, state: BookmarkState,

View File

@ -21,6 +21,7 @@ package org.kiwix.kiwixmobile.core.page.bookmark.viewmodel.effects
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao
import org.kiwix.kiwixmobile.core.dao.PageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem import org.kiwix.kiwixmobile.core.page.bookmark.adapter.LibkiwixBookmarkItem
@ -34,14 +35,14 @@ import javax.inject.Inject
data class ShowDeleteBookmarksDialog( data class ShowDeleteBookmarksDialog(
private val effects: PublishProcessor<SideEffect<*>>, private val effects: PublishProcessor<SideEffect<*>>,
private val state: PageState<LibkiwixBookmarkItem>, private val state: PageState<LibkiwixBookmarkItem>,
private val pageDao: PageDao private val basePageDao: BasePageDao
) : SideEffect<Unit> { ) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower @Inject lateinit var dialogShower: DialogShower
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
activity.cachedComponent.inject(this) activity.cachedComponent.inject(this)
dialogShower.show( dialogShower.show(
if (state.isInSelectionState) DeleteSelectedBookmarks else DeleteAllBookmarks, if (state.isInSelectionState) DeleteSelectedBookmarks else DeleteAllBookmarks,
{ effects.offer(DeletePageItems(state, pageDao)) } { effects.offer(DeletePageItems(state, basePageDao)) }
) )
} }
} }

View File

@ -19,6 +19,7 @@
package org.kiwix.kiwixmobile.core.page.history.viewmodel package org.kiwix.kiwixmobile.core.page.history.viewmodel
import org.kiwix.kiwixmobile.core.dao.HistoryDao import org.kiwix.kiwixmobile.core.dao.HistoryDao
import org.kiwix.kiwixmobile.core.dao.HistoryRoomDao
import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem.HistoryItem import org.kiwix.kiwixmobile.core.page.history.adapter.HistoryListItem.HistoryItem
import org.kiwix.kiwixmobile.core.page.history.viewmodel.effects.ShowDeleteHistoryDialog import org.kiwix.kiwixmobile.core.page.history.viewmodel.effects.ShowDeleteHistoryDialog
import org.kiwix.kiwixmobile.core.page.history.viewmodel.effects.UpdateAllHistoryPreference import org.kiwix.kiwixmobile.core.page.history.viewmodel.effects.UpdateAllHistoryPreference
@ -29,10 +30,10 @@ import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import javax.inject.Inject import javax.inject.Inject
class HistoryViewModel @Inject constructor( class HistoryViewModel @Inject constructor(
historyDao: HistoryDao, historyRoomDao: HistoryRoomDao,
zimReaderContainer: ZimReaderContainer, zimReaderContainer: ZimReaderContainer,
sharedPrefs: SharedPreferenceUtil sharedPrefs: SharedPreferenceUtil
) : PageViewModel<HistoryItem, HistoryState>(historyDao, sharedPrefs, zimReaderContainer) { ) : PageViewModel<HistoryItem, HistoryState>(historyRoomDao, sharedPrefs, zimReaderContainer) {
override fun initialState(): HistoryState = override fun initialState(): HistoryState =
HistoryState(emptyList(), sharedPreferenceUtil.showHistoryAllBooks, zimReaderContainer.id) HistoryState(emptyList(), sharedPreferenceUtil.showHistoryAllBooks, zimReaderContainer.id)
@ -58,7 +59,7 @@ class HistoryViewModel @Inject constructor(
} }
override fun createDeletePageDialogEffect(state: HistoryState) = override fun createDeletePageDialogEffect(state: HistoryState) =
ShowDeleteHistoryDialog(effects, state, pageDao) ShowDeleteHistoryDialog(effects, state, basePageDao)
override fun deselectAllPages(state: HistoryState): HistoryState = override fun deselectAllPages(state: HistoryState): HistoryState =
state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) }) state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })

View File

@ -21,6 +21,7 @@ package org.kiwix.kiwixmobile.core.page.history.viewmodel.effects
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao
import org.kiwix.kiwixmobile.core.dao.PageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
import org.kiwix.kiwixmobile.core.page.history.viewmodel.HistoryState import org.kiwix.kiwixmobile.core.page.history.viewmodel.HistoryState
@ -33,13 +34,13 @@ import javax.inject.Inject
data class ShowDeleteHistoryDialog( data class ShowDeleteHistoryDialog(
private val effects: PublishProcessor<SideEffect<*>>, private val effects: PublishProcessor<SideEffect<*>>,
private val state: HistoryState, private val state: HistoryState,
private val pageDao: PageDao private val basePageDao: BasePageDao
) : SideEffect<Unit> { ) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower @Inject lateinit var dialogShower: DialogShower
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
activity.cachedComponent.inject(this) activity.cachedComponent.inject(this)
dialogShower.show(if (state.isInSelectionState) DeleteSelectedHistory else DeleteAllHistory, { dialogShower.show(if (state.isInSelectionState) DeleteSelectedHistory else DeleteAllHistory, {
effects.offer(DeletePageItems(state, pageDao)) effects.offer(DeletePageItems(state, basePageDao))
}) })
} }
} }

View File

@ -66,7 +66,7 @@ class NotesViewModel @Inject constructor(
state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) }) state.copy(pageItems = state.pageItems.map { it.copy(isSelected = false) })
override fun createDeletePageDialogEffect(state: NotesState) = override fun createDeletePageDialogEffect(state: NotesState) =
ShowDeleteNotesDialog(effects, state, pageDao) ShowDeleteNotesDialog(effects, state, basePageDao)
override fun onItemClick(page: Page) = override fun onItemClick(page: Page) =
ShowOpenNoteDialog(effects, page, zimReaderContainer) ShowOpenNoteDialog(effects, page, zimReaderContainer)

View File

@ -22,6 +22,7 @@ import org.kiwix.kiwixmobile.core.utils.files.Log
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao
import org.kiwix.kiwixmobile.core.dao.PageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.cachedComponent
import org.kiwix.kiwixmobile.core.page.notes.viewmodel.NotesState import org.kiwix.kiwixmobile.core.page.notes.viewmodel.NotesState
@ -34,7 +35,7 @@ import javax.inject.Inject
data class ShowDeleteNotesDialog( data class ShowDeleteNotesDialog(
private val effects: PublishProcessor<SideEffect<*>>, private val effects: PublishProcessor<SideEffect<*>>,
private val state: NotesState, private val state: NotesState,
private val pageDao: PageDao private val basePageDao: BasePageDao
) : SideEffect<Unit> { ) : SideEffect<Unit> {
@Inject lateinit var dialogShower: DialogShower @Inject lateinit var dialogShower: DialogShower
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
@ -43,7 +44,7 @@ data class ShowDeleteNotesDialog(
dialogShower.show( dialogShower.show(
if (state.isInSelectionState) DeleteSelectedNotes else DeleteAllNotes, if (state.isInSelectionState) DeleteSelectedNotes else DeleteAllNotes,
{ {
effects.offer(DeletePageItems(state, pageDao)) effects.offer(DeletePageItems(state, basePageDao))
} }
) )
} }

View File

@ -20,12 +20,16 @@ package org.kiwix.kiwixmobile.core.page.viewmodel
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable import io.reactivex.disposables.Disposable
import io.reactivex.processors.PublishProcessor import io.reactivex.processors.PublishProcessor
import io.reactivex.schedulers.Schedulers import io.reactivex.schedulers.Schedulers
import kotlinx.coroutines.launch
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao
import org.kiwix.kiwixmobile.core.dao.PageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.dao.PageRoomDao
import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.adapter.Page
import org.kiwix.kiwixmobile.core.page.viewmodel.Action.Exit import org.kiwix.kiwixmobile.core.page.viewmodel.Action.Exit
import org.kiwix.kiwixmobile.core.page.viewmodel.Action.ExitActionModeMenu import org.kiwix.kiwixmobile.core.page.viewmodel.Action.ExitActionModeMenu
@ -42,7 +46,7 @@ import org.kiwix.kiwixmobile.core.search.viewmodel.effects.PopFragmentBackstack
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
abstract class PageViewModel<T : Page, S : PageState<T>>( abstract class PageViewModel<T : Page, S : PageState<T>>(
protected val pageDao: PageDao, protected val basePageDao: BasePageDao,
val sharedPreferenceUtil: SharedPreferenceUtil, val sharedPreferenceUtil: SharedPreferenceUtil,
val zimReaderContainer: ZimReaderContainer val zimReaderContainer: ZimReaderContainer
) : ViewModel() { ) : ViewModel() {
@ -70,11 +74,25 @@ abstract class PageViewModel<T : Page, S : PageState<T>>(
.subscribe(state::postValue, Throwable::printStackTrace) .subscribe(state::postValue, Throwable::printStackTrace)
protected fun addDisposablesToCompositeDisposable() { protected fun addDisposablesToCompositeDisposable() {
compositeDisposable.addAll( when (basePageDao) {
viewStateReducer(), is PageDao -> {
pageDao.pages().subscribeOn(Schedulers.io()) compositeDisposable.addAll(
.subscribe({ actions.offer(UpdatePages(it)) }, Throwable::printStackTrace) viewStateReducer(),
) basePageDao.pages().subscribeOn(Schedulers.io())
.subscribe({ actions.offer(UpdatePages(it)) }, Throwable::printStackTrace)
)
}
is PageRoomDao -> {
viewModelScope.launch {
try {
// basePageDao.pages().collect(::UpdatePages)
} catch (exception: Exception) {
exception.printStackTrace()
}
}
}
}
} }
private fun reduce(action: Action, state: S): S = when (action) { private fun reduce(action: Action, state: S): S = when (action) {

View File

@ -20,19 +20,20 @@ package org.kiwix.kiwixmobile.core.page.viewmodel.effects
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import org.kiwix.kiwixmobile.core.base.SideEffect import org.kiwix.kiwixmobile.core.base.SideEffect
import org.kiwix.kiwixmobile.core.dao.BasePageDao
import org.kiwix.kiwixmobile.core.dao.PageDao import org.kiwix.kiwixmobile.core.dao.PageDao
import org.kiwix.kiwixmobile.core.page.adapter.Page import org.kiwix.kiwixmobile.core.page.adapter.Page
import org.kiwix.kiwixmobile.core.page.viewmodel.PageState import org.kiwix.kiwixmobile.core.page.viewmodel.PageState
data class DeletePageItems( data class DeletePageItems(
private val state: PageState<*>, private val state: PageState<*>,
private val pageDao: PageDao private val basePageDao: BasePageDao
) : SideEffect<Unit> { ) : SideEffect<Unit> {
override fun invokeWith(activity: AppCompatActivity) { override fun invokeWith(activity: AppCompatActivity) {
if (state.isInSelectionState) { if (state.isInSelectionState) {
pageDao.deletePages(state.pageItems.filter(Page::isSelected)) basePageDao.deletePages(state.pageItems.filter(Page::isSelected))
} else { } else {
pageDao.deletePages(state.pageItems) basePageDao.deletePages(state.pageItems)
} }
} }
} }