diff --git a/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapter.kt b/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapter.kt index e70641d0e5..42d474115e 100644 --- a/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapter.kt +++ b/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapter.kt @@ -17,16 +17,16 @@ import org.ccci.gto.android.common.recyclerview.advrecyclerview.draggable.Simple import org.cru.godtools.databinding.ToolsListItemToolBinding import org.cru.godtools.model.Tool -private const val VIEW_MODEL_KEY_PREFIX = - "org.cru.godtools.ui.tools.ToolsAdapter:org.cru.godtools.ui.tools.ToolsAdapterToolViewModel" private typealias VH = DataBindingDraggableItemViewHolder -class ToolsAdapter(lifecycleOwner: LifecycleOwner, private val viewModelProvider: ViewModelProvider) : +class ToolsAdapter(lifecycleOwner: LifecycleOwner, viewModelProvider: ViewModelProvider) : SimpleDataBindingDraggableItemAdapter(lifecycleOwner), Observer> { init { setHasStableIds(true) } + private val viewModel = viewModelProvider.get(ToolsAdapterViewModel::class.java) + val callbacks = ObservableField() private var tools: List? = null set(value) { @@ -54,16 +54,14 @@ class ToolsAdapter(lifecycleOwner: LifecycleOwner, private val viewModelProvider override fun onBindViewDataBinding(binding: ToolsListItemToolBinding, position: Int) { val tool = getItem(position) - val code = tool?.code - val viewModel = viewModelProvider.get("$VIEW_MODEL_KEY_PREFIX:$code", ToolsAdapterToolViewModel::class.java) - .also { it.toolCode.value = code } + val toolViewModel = tool?.code?.let { viewModel.getToolViewModel(it) } binding.tool = tool - binding.setDownloadProgress(viewModel.downloadProgress) - binding.setBanner(viewModel.banner) - binding.primaryTranslation = viewModel.firstTranslation - binding.parallelTranslation = viewModel.parallelTranslation - binding.parallelLanguage = viewModel.parallelLanguage + binding.setDownloadProgress(toolViewModel?.downloadProgress) + binding.setBanner(toolViewModel?.banner) + binding.primaryTranslation = toolViewModel?.firstTranslation + binding.parallelTranslation = toolViewModel?.parallelTranslation + binding.parallelLanguage = toolViewModel?.parallelLanguage } override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) { diff --git a/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapterToolViewModel.kt b/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapterToolViewModel.kt deleted file mode 100644 index 5c5b325066..0000000000 --- a/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapterToolViewModel.kt +++ /dev/null @@ -1,73 +0,0 @@ -package org.cru.godtools.ui.tools - -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.distinctUntilChanged -import androidx.lifecycle.map -import androidx.lifecycle.switchMap -import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject -import org.ccci.gto.android.common.androidx.lifecycle.combineWith -import org.ccci.gto.android.common.androidx.lifecycle.emptyLiveData -import org.ccci.gto.android.common.androidx.lifecycle.orEmpty -import org.ccci.gto.android.common.androidx.lifecycle.switchCombineWith -import org.ccci.gto.android.common.db.Query -import org.ccci.gto.android.common.db.findLiveData -import org.ccci.gto.android.common.db.getAsLiveData -import org.cru.godtools.base.Settings -import org.cru.godtools.download.manager.GodToolsDownloadManager -import org.cru.godtools.model.Attachment -import org.cru.godtools.model.Language -import org.keynote.godtools.android.db.Contract.AttachmentTable -import org.keynote.godtools.android.db.Contract.ToolTable -import org.keynote.godtools.android.db.GodToolsDao - -@HiltViewModel -class ToolsAdapterToolViewModel @Inject constructor( - private val dao: GodToolsDao, - private val downloadManager: GodToolsDownloadManager, - settings: Settings -) : ViewModel() { - internal val toolCode = MutableLiveData() - private val distinctToolCode = toolCode.distinctUntilChanged() - - val banner = distinctToolCode.switchMap { - it?.let { - Query.select() - .join(AttachmentTable.SQL_JOIN_TOOL) - .where( - ToolTable.FIELD_CODE.eq(it) - .and(ToolTable.FIELD_BANNER.eq(AttachmentTable.FIELD_ID)) - .and(AttachmentTable.SQL_WHERE_DOWNLOADED) - ) - .limit(1) - .getAsLiveData(dao) - }.orEmpty() - }.map { it?.firstOrNull() } - - private val primaryTranslation = distinctToolCode.switchCombineWith(settings.primaryLanguageLiveData) { c, l -> - dao.getLatestTranslationLiveData(c, l) - } - private val defaultTranslation = - distinctToolCode.switchMap { dao.getLatestTranslationLiveData(it, Settings.defaultLanguage) } - internal val firstTranslation = primaryTranslation.combineWith(defaultTranslation) { p, d -> p ?: d } - internal val parallelTranslation = distinctToolCode.switchCombineWith(settings.parallelLanguageLiveData) { c, l -> - dao.getLatestTranslationLiveData(c, l) - } - - internal val parallelLanguage = parallelTranslation.switchMap { t -> - t?.languageCode?.let { dao.findLiveData(it) }.orEmpty() - } - - internal val downloadProgress = distinctToolCode.switchCombineWith( - primaryTranslation, defaultTranslation, parallelTranslation - ) { code, primary, default, parallel -> - when { - code == null -> emptyLiveData() - primary != null -> downloadManager.getDownloadProgressLiveData(code, primary.languageCode) - default != null -> downloadManager.getDownloadProgressLiveData(code, default.languageCode) - parallel != null -> downloadManager.getDownloadProgressLiveData(code, parallel.languageCode) - else -> emptyLiveData() - } - } -} diff --git a/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapterViewModel.kt b/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapterViewModel.kt new file mode 100644 index 0000000000..2dcb4b847d --- /dev/null +++ b/app/src/main/java/org/cru/godtools/ui/tools/ToolsAdapterViewModel.kt @@ -0,0 +1,65 @@ +package org.cru.godtools.ui.tools + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.map +import androidx.lifecycle.switchMap +import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject +import org.ccci.gto.android.common.androidx.lifecycle.combineWith +import org.ccci.gto.android.common.androidx.lifecycle.emptyLiveData +import org.ccci.gto.android.common.androidx.lifecycle.orEmpty +import org.ccci.gto.android.common.androidx.lifecycle.switchCombineWith +import org.ccci.gto.android.common.db.Query +import org.ccci.gto.android.common.db.findLiveData +import org.ccci.gto.android.common.db.getAsLiveData +import org.cru.godtools.base.Settings +import org.cru.godtools.download.manager.GodToolsDownloadManager +import org.cru.godtools.model.Attachment +import org.cru.godtools.model.Language +import org.keynote.godtools.android.db.Contract.AttachmentTable +import org.keynote.godtools.android.db.Contract.ToolTable +import org.keynote.godtools.android.db.GodToolsDao + +@HiltViewModel +class ToolsAdapterViewModel @Inject constructor( + private val dao: GodToolsDao, + private val downloadManager: GodToolsDownloadManager, + private val settings: Settings +) : ViewModel() { + private val toolViewModels = mutableMapOf() + fun getToolViewModel(tool: String) = toolViewModels.getOrPut(tool) { ToolViewModel(tool) } + + inner class ToolViewModel(private val tool: String) { + val banner = Query.select() + .join(AttachmentTable.SQL_JOIN_TOOL) + .where( + ToolTable.FIELD_CODE.eq(tool) + .and(ToolTable.FIELD_BANNER.eq(AttachmentTable.FIELD_ID)) + .and(AttachmentTable.SQL_WHERE_DOWNLOADED) + ) + .limit(1) + .getAsLiveData(dao) + .map { it.firstOrNull() } + + private val primaryTranslation = + settings.primaryLanguageLiveData.switchMap { dao.getLatestTranslationLiveData(tool, it) } + private val defaultTranslation = dao.getLatestTranslationLiveData(tool, Settings.defaultLanguage) + internal val firstTranslation = primaryTranslation.combineWith(defaultTranslation) { p, d -> p ?: d } + internal val parallelTranslation = + settings.parallelLanguageLiveData.switchMap { dao.getLatestTranslationLiveData(tool, it) } + + internal val parallelLanguage = parallelTranslation.switchMap { t -> + t?.languageCode?.let { dao.findLiveData(it) }.orEmpty() + } + + internal val downloadProgress = + primaryTranslation.switchCombineWith(defaultTranslation, parallelTranslation) { prim, def, para -> + when { + prim != null -> downloadManager.getDownloadProgressLiveData(tool, prim.languageCode) + def != null -> downloadManager.getDownloadProgressLiveData(tool, def.languageCode) + para != null -> downloadManager.getDownloadProgressLiveData(tool, para.languageCode) + else -> emptyLiveData() + } + } + } +}