diff --git a/app/build.gradle b/app/build.gradle index 5bfa5629..e7193747 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -79,8 +79,7 @@ dependencies { implementation 'android.arch.lifecycle:extensions:1.1.1' implementation 'android.arch.lifecycle:viewmodel:1.1.1' - implementation 'io.insert-koin:koin-core:3.1.5' - implementation 'io.insert-koin:koin-android:3.1.5' + implementation(libs.koin.android) implementation "androidx.room:room-runtime:2.5.2" kapt "androidx.room:room-compiler:2.5.2" diff --git a/app/src/androidTest/java/com/willowtree/vocable/settings/EditCategoryPhrasesViewModelTest.kt b/app/src/androidTest/java/com/willowtree/vocable/settings/EditCategoryPhrasesViewModelTest.kt deleted file mode 100644 index 953c140e..00000000 --- a/app/src/androidTest/java/com/willowtree/vocable/settings/EditCategoryPhrasesViewModelTest.kt +++ /dev/null @@ -1,83 +0,0 @@ -package com.willowtree.vocable.settings - -import androidx.arch.core.executor.testing.InstantTaskExecutorRule -import com.willowtree.vocable.MainDispatcherRule -import com.willowtree.vocable.presets.Category -import com.willowtree.vocable.presets.PresetCategories -import com.willowtree.vocable.presets.PresetPhrase -import com.willowtree.vocable.room.PresetPhrasesRepository -import com.willowtree.vocable.utility.VocableKoinTestRule -import junit.framework.TestCase.assertEquals -import kotlinx.coroutines.runBlocking -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.koin.core.component.KoinComponent -import org.koin.core.component.get - -class EditCategoryPhrasesViewModelTest: KoinComponent { - - @get:Rule - val koinTestRule = VocableKoinTestRule() - - @get:Rule - val mainDispatcherRule = MainDispatcherRule() - - @get:Rule - val instantTaskExecutorRule = InstantTaskExecutorRule() - - private lateinit var viewModel: EditCategoryPhrasesViewModel - - @Before - fun setUp() { - val presetPhrasesRepository: PresetPhrasesRepository = get() - runBlocking { - presetPhrasesRepository.populateDatabase() - } - viewModel = get() - } - - @Test - fun getCategoryName_withRecents_returnsRecents() { - val result = viewModel.getCategoryName(Category.Recents(false, 0)) - assertEquals("Recents", result) - } - - @Test - fun getCategoryName_withPresetCategory_returnsCategoryName() { - val result = viewModel.getCategoryName(Category.PresetCategory(PresetCategories.GENERAL.id, 0, false)) - assertEquals("General", result) - } - - @Test - fun fetchCategoryPhrases_withGeneral_returnsCorrectPhraseList() { - viewModel.fetchCategoryPhrases(Category.PresetCategory(PresetCategories.GENERAL.id, 0, false)) - viewModel.categoryPhraseList.observeForever { - assertEquals(9, it.size) - assertEquals("preset_please", it[0].phraseId) - } - } - - @Test - fun deletePhraseFromCategory_withPlease_deletesPleaseCorrectly() { - viewModel.deletePhraseFromCategory( - phrase = PresetPhrase( - phraseId = "preset_please", - sortOrder = 0, - lastSpokenDate = 0, - deleted = false, - parentCategoryId = PresetCategories.GENERAL.id - ), - category = Category.PresetCategory( - categoryId = PresetCategories.GENERAL.id, - sortOrder = 0, - hidden = false - ) - ) - - viewModel.categoryPhraseList.observeForever { - assertEquals(8, it.size) - assertEquals("preset_thank_you", it[0].phraseId) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/AppKoinModule.kt b/app/src/main/java/com/willowtree/vocable/AppKoinModule.kt index ddd74202..e0224cb7 100644 --- a/app/src/main/java/com/willowtree/vocable/AppKoinModule.kt +++ b/app/src/main/java/com/willowtree/vocable/AppKoinModule.kt @@ -103,7 +103,7 @@ val vocableKoinModule = module { single { VocableEnvironmentImpl() } viewModel { PresetsViewModel(get(), get(), get(named())) } viewModel { EditCategoriesViewModel(get()) } - viewModel { EditCategoryPhrasesViewModel(get(), get()) } + viewModel { EditCategoryPhrasesViewModel(get(), get(), get()) } viewModel { AddUpdateCategoryViewModel(get(), get(), get()) } viewModel { EditCategoryMenuViewModel(get()) } } \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/IPhrasesUseCase.kt b/app/src/main/java/com/willowtree/vocable/IPhrasesUseCase.kt index 695a4a7a..b61338c8 100644 --- a/app/src/main/java/com/willowtree/vocable/IPhrasesUseCase.kt +++ b/app/src/main/java/com/willowtree/vocable/IPhrasesUseCase.kt @@ -2,11 +2,14 @@ package com.willowtree.vocable import com.willowtree.vocable.presets.Phrase import com.willowtree.vocable.utils.locale.LocalesWithText +import kotlinx.coroutines.flow.Flow interface IPhrasesUseCase { suspend fun getPhrasesForCategory(categoryId: String): List + fun getPhrasesForCategoryFlow(categoryId: String): Flow> + suspend fun updatePhraseLastSpokenTime(phraseId: String) suspend fun deletePhrase(phraseId: String) diff --git a/app/src/main/java/com/willowtree/vocable/MainActivity.kt b/app/src/main/java/com/willowtree/vocable/MainActivity.kt index 5d904909..81047930 100644 --- a/app/src/main/java/com/willowtree/vocable/MainActivity.kt +++ b/app/src/main/java/com/willowtree/vocable/MainActivity.kt @@ -22,8 +22,7 @@ import io.github.inflationx.viewpump.ViewPumpContextWrapper import kotlinx.coroutines.launch import org.koin.android.ext.android.inject import org.koin.androidx.scope.ScopeActivity -import org.koin.androidx.viewmodel.ViewModelOwner -import org.koin.androidx.viewmodel.scope.getViewModel +import org.koin.androidx.viewmodel.ext.android.getViewModel class MainActivity : ScopeActivity() { @@ -41,7 +40,7 @@ class MainActivity : ScopeActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - faceTrackingViewModel = scope.getViewModel(owner = { ViewModelOwner.from(this) }) + faceTrackingViewModel = getViewModel() binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) diff --git a/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt b/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt index ff54cfcb..39c189ee 100644 --- a/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt +++ b/app/src/main/java/com/willowtree/vocable/PhrasesUseCase.kt @@ -12,6 +12,8 @@ import com.willowtree.vocable.utils.DateProvider import com.willowtree.vocable.utils.UUIDProvider import com.willowtree.vocable.utils.locale.LocaleProvider import com.willowtree.vocable.utils.locale.LocalesWithText +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.combine class PhrasesUseCase( private val legacyPhrasesRepository: ILegacyCategoriesAndPhrasesRepository, @@ -31,6 +33,23 @@ class PhrasesUseCase( presetPhrasesRepository.getPhrasesForCategory(categoryId) } + override fun getPhrasesForCategoryFlow(categoryId: String): Flow> { + return combine( + presetPhrasesRepository.getRecentPhrasesFlow(), + storedPhrasesRepository.getRecentPhrasesFlow(), + storedPhrasesRepository.getPhrasesForCategoryFlow(categoryId), + presetPhrasesRepository.getPhrasesForCategoryFlow(categoryId) + ) { recentPresets, recentStored, stored, presets -> + if (categoryId == PresetCategories.RECENTS.id) { + (recentPresets + recentStored) + .sortedByDescending { it.lastSpokenDate } + .take(8) + } else { + stored + presets + } + } + } + override suspend fun updatePhraseLastSpokenTime(phraseId: String) { storedPhrasesRepository.updatePhraseLastSpokenTime(phraseId) presetPhrasesRepository.updatePhraseLastSpokenTime(phraseId) @@ -54,6 +73,7 @@ class PhrasesUseCase( localizedUtterance = localizedUtterance, ) } + is PresetPhrase -> { presetPhrasesRepository.deletePhrase(phraseId = phraseId) // add a custom phrase to "shadow" over the preset @@ -69,24 +89,29 @@ class PhrasesUseCase( ) } + null -> throw IllegalArgumentException("Phrase with id $phraseId not found") } } override suspend fun addPhrase(localizedUtterance: LocalesWithText, parentCategoryId: String) { if (parentCategoryId != PresetCategories.RECENTS.id) { - storedPhrasesRepository.addPhrase(PhraseDto( - phraseId = uuidProvider.randomUUIDString(), - parentCategoryId = parentCategoryId, - creationDate = dateProvider.currentTimeMillis(), - lastSpokenDate = null, - localizedUtterance = localizedUtterance, - sortOrder = legacyPhrasesRepository.getPhrasesForCategory(parentCategoryId).size - )) + storedPhrasesRepository.addPhrase( + PhraseDto( + phraseId = uuidProvider.randomUUIDString(), + parentCategoryId = parentCategoryId, + creationDate = dateProvider.currentTimeMillis(), + lastSpokenDate = null, + localizedUtterance = localizedUtterance, + sortOrder = legacyPhrasesRepository.getPhrasesForCategory(parentCategoryId).size + ) + ) } else { - throw Exception("The 'Recents' category is not a true category -" + - " it is a filter applied to true categories. Therefore, saving phrases from " + - "the Recents 'category' is not supported.") + throw Exception( + "The 'Recents' category is not a true category -" + + " it is a filter applied to true categories. Therefore, saving phrases from " + + "the Recents 'category' is not supported." + ) } } } \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/presets/CategoriesFragment.kt b/app/src/main/java/com/willowtree/vocable/presets/CategoriesFragment.kt index 71be5d1f..fd0185ed 100644 --- a/app/src/main/java/com/willowtree/vocable/presets/CategoriesFragment.kt +++ b/app/src/main/java/com/willowtree/vocable/presets/CategoriesFragment.kt @@ -15,8 +15,7 @@ import com.willowtree.vocable.customviews.CategoryButton import com.willowtree.vocable.customviews.PointerListener import com.willowtree.vocable.databinding.CategoriesFragmentBinding import com.willowtree.vocable.databinding.CategoryButtonBinding -import org.koin.androidx.viewmodel.ViewModelOwner -import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.activityViewModel class CategoriesFragment : BaseFragment() { @@ -35,9 +34,7 @@ class CategoriesFragment : BaseFragment() { override val bindingInflater: BindingInflater = CategoriesFragmentBinding::inflate - private val viewModel: PresetsViewModel by viewModel(owner = { - ViewModelOwner.from(requireActivity()) - }) + private val viewModel: PresetsViewModel by activityViewModel() private val allViews = mutableListOf() private var maxCategories = 1 diff --git a/app/src/main/java/com/willowtree/vocable/presets/PhrasesFragment.kt b/app/src/main/java/com/willowtree/vocable/presets/PhrasesFragment.kt index 32c61d7d..fa6454b5 100644 --- a/app/src/main/java/com/willowtree/vocable/presets/PhrasesFragment.kt +++ b/app/src/main/java/com/willowtree/vocable/presets/PhrasesFragment.kt @@ -11,13 +11,10 @@ import com.willowtree.vocable.R import com.willowtree.vocable.databinding.FragmentPhrasesBinding import com.willowtree.vocable.presets.adapter.PhraseAdapter import com.willowtree.vocable.utils.ItemOffsetDecoration -import org.koin.androidx.viewmodel.ViewModelOwner -import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.activityViewModel class PhrasesFragment : BaseFragment() { - private val presetsViewModel: PresetsViewModel by viewModel(owner = { - ViewModelOwner.from(requireActivity()) - }) + private val presetsViewModel: PresetsViewModel by activityViewModel() companion object { private const val KEY_PHRASES = "KEY_PHRASES" diff --git a/app/src/main/java/com/willowtree/vocable/presets/PresetsFragment.kt b/app/src/main/java/com/willowtree/vocable/presets/PresetsFragment.kt index ba7ad8c4..92885266 100644 --- a/app/src/main/java/com/willowtree/vocable/presets/PresetsFragment.kt +++ b/app/src/main/java/com/willowtree/vocable/presets/PresetsFragment.kt @@ -20,8 +20,7 @@ import com.willowtree.vocable.databinding.FragmentPresetsBinding import com.willowtree.vocable.utils.SpokenText import com.willowtree.vocable.utils.VocableFragmentStateAdapter import com.willowtree.vocable.utils.VocableTextToSpeech -import org.koin.androidx.viewmodel.ViewModelOwner -import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.activityViewModel class PresetsFragment : BaseFragment() { @@ -34,9 +33,7 @@ class PresetsFragment : BaseFragment() { private var isPortraitMode = true private var isTabletMode = false - private val presetsViewModel: PresetsViewModel by viewModel(owner = { - ViewModelOwner.from(requireActivity()) - }) + private val presetsViewModel: PresetsViewModel by activityViewModel() private lateinit var categoriesAdapter: CategoriesPagerAdapter private lateinit var phrasesAdapter: PhrasesPagerAdapter diff --git a/app/src/main/java/com/willowtree/vocable/room/PhraseDao.kt b/app/src/main/java/com/willowtree/vocable/room/PhraseDao.kt index 0abea269..11be3b63 100644 --- a/app/src/main/java/com/willowtree/vocable/room/PhraseDao.kt +++ b/app/src/main/java/com/willowtree/vocable/room/PhraseDao.kt @@ -1,6 +1,12 @@ package com.willowtree.vocable.room -import androidx.room.* +import androidx.room.Dao +import androidx.room.Delete +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import androidx.room.Update +import kotlinx.coroutines.flow.Flow @Dao interface PhraseDao { @@ -26,9 +32,15 @@ interface PhraseDao { @Query("SELECT * FROM Phrase WHERE last_spoken_date IS NOT NULL ORDER BY last_spoken_date DESC LIMIT 8") suspend fun getRecentPhrases(): List + @Query("SELECT * FROM Phrase WHERE last_spoken_date IS NOT NULL ORDER BY last_spoken_date DESC LIMIT 8") + fun getRecentPhrasesFlow(): Flow> + @Query("SELECT * FROM Phrase WHERE parent_category_id == :categoryId") suspend fun getPhrasesForCategory(categoryId: String): List + @Query("SELECT * FROM Phrase WHERE parent_category_id == :categoryId") + fun getPhrasesForCategoryFlow(categoryId: String): Flow> + @Query("SELECT * FROM Phrase WHERE phrase_id == :phraseId") suspend fun getPhrase(phraseId: String): PhraseDto? } diff --git a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt index 80e7fc7a..72f13288 100644 --- a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt +++ b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesDao.kt @@ -5,6 +5,7 @@ import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Update +import kotlinx.coroutines.flow.Flow @Dao interface PresetPhrasesDao { @@ -21,9 +22,15 @@ interface PresetPhrasesDao { @Query("SELECT * FROM PresetPhrase WHERE last_spoken_date IS NOT NULL ORDER BY last_spoken_date DESC LIMIT 8") suspend fun getRecentPhrases(): List + @Query("SELECT * FROM PresetPhrase WHERE last_spoken_date IS NOT NULL ORDER BY last_spoken_date DESC LIMIT 8") + fun getRecentPhrasesFlow(): Flow> + @Query("SELECT * FROM PresetPhrase WHERE parent_category_id = :categoryId") suspend fun getPhrasesForCategory(categoryId: String): List + @Query("SELECT * FROM PresetPhrase WHERE parent_category_id = :categoryId") + fun getPhrasesForCategoryFlow(categoryId: String): Flow> + @Query("SELECT * FROM PresetPhrase WHERE phrase_id = :phraseId") suspend fun getPhrase(phraseId: String): PresetPhraseDto? diff --git a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt index d86937ae..d688a5f7 100644 --- a/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/PresetPhrasesRepository.kt @@ -1,13 +1,16 @@ package com.willowtree.vocable.room import com.willowtree.vocable.presets.PresetPhrase +import kotlinx.coroutines.flow.Flow interface PresetPhrasesRepository { suspend fun populateDatabase() suspend fun getAllPresetPhrases(): List suspend fun updatePhraseLastSpokenTime(phraseId: String) suspend fun getRecentPhrases() : List + fun getRecentPhrasesFlow(): Flow> suspend fun getPhrasesForCategory(categoryId: String): List + fun getPhrasesForCategoryFlow(categoryId: String): Flow> suspend fun getPhrase(phraseId: String): PresetPhrase? suspend fun deletePhrase(phraseId: String) } \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt index dc8e33d0..cdca34ea 100644 --- a/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/RoomPresetPhrasesRepository.kt @@ -5,6 +5,8 @@ import com.willowtree.vocable.presets.PresetCategories import com.willowtree.vocable.presets.PresetPhrase import com.willowtree.vocable.presets.asPhrase import com.willowtree.vocable.utils.DateProvider +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import org.koin.core.context.GlobalContext.get @@ -37,7 +39,12 @@ class RoomPresetPhrasesRepository( override suspend fun getRecentPhrases(): List { return presetPhrasesDao.getRecentPhrases() .filterDeletedPresets() - .map { it.asPhrase()} + .map { it.asPhrase() } + } + + override fun getRecentPhrasesFlow(): Flow> { + return presetPhrasesDao.getRecentPhrasesFlow() + .map { phraseList -> phraseList.filterDeletedPresets().map { it.asPhrase() } } } override suspend fun getPhrasesForCategory(categoryId: String): List { @@ -46,6 +53,11 @@ class RoomPresetPhrasesRepository( .map { it.asPhrase() } } + override fun getPhrasesForCategoryFlow(categoryId: String): Flow> { + return presetPhrasesDao.getPhrasesForCategoryFlow(categoryId) + .map { phraseList -> phraseList.filterDeletedPresets().map { it.asPhrase() } } + } + override suspend fun getPhrase(phraseId: String): PresetPhrase? { return presetPhrasesDao.getPhrase(phraseId)?.asPhrase() } @@ -54,7 +66,7 @@ class RoomPresetPhrasesRepository( presetPhrasesDao.deletePhrase(phraseId, deleted = true) } - private fun List.filterDeletedPresets() : List { + private fun List.filterDeletedPresets(): List { return filterNot { it.deleted } } diff --git a/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt index 1e326cce..ff5628fb 100644 --- a/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/RoomStoredPhrasesRepository.kt @@ -4,6 +4,8 @@ import com.willowtree.vocable.presets.Phrase import com.willowtree.vocable.presets.asPhrase import com.willowtree.vocable.utils.DateProvider import com.willowtree.vocable.utils.locale.LocalesWithText +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map class RoomStoredPhrasesRepository( private val database: VocableDatabase, @@ -26,10 +28,20 @@ class RoomStoredPhrasesRepository( return database.phraseDao().getRecentPhrases().map { it.asPhrase() } } + override fun getRecentPhrasesFlow(): Flow> { + return database.phraseDao().getRecentPhrasesFlow() + .map { phraseList -> phraseList.map { it.asPhrase() } } + } + override suspend fun getPhrasesForCategory(categoryId: String): List { return database.phraseDao().getPhrasesForCategory(categoryId).map { it.asPhrase() } } + override fun getPhrasesForCategoryFlow(categoryId: String): Flow> { + return database.phraseDao().getPhrasesForCategoryFlow(categoryId) + .map { phraseList -> phraseList.map { it.asPhrase() } } + } + override suspend fun getPhrase(phraseId: String): Phrase? { return database.phraseDao().getPhrase(phraseId)?.asPhrase() } diff --git a/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt b/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt index aaec6384..66c27f43 100644 --- a/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt +++ b/app/src/main/java/com/willowtree/vocable/room/StoredPhrasesRepository.kt @@ -2,12 +2,15 @@ package com.willowtree.vocable.room import com.willowtree.vocable.presets.Phrase import com.willowtree.vocable.utils.locale.LocalesWithText +import kotlinx.coroutines.flow.Flow interface StoredPhrasesRepository { suspend fun addPhrase(phrase: PhraseDto) suspend fun updatePhraseLastSpokenTime(phraseId: String) suspend fun getRecentPhrases(): List + fun getRecentPhrasesFlow(): Flow> suspend fun getPhrasesForCategory(categoryId: String): List + fun getPhrasesForCategoryFlow(categoryId: String): Flow> suspend fun getPhrase(phraseId: String): Phrase? suspend fun updatePhrase(phrase: PhraseDto) suspend fun updatePhraseLocalizedUtterance( diff --git a/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesFragment.kt b/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesFragment.kt index c840c491..7ca2af7c 100644 --- a/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesFragment.kt +++ b/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesFragment.kt @@ -17,8 +17,7 @@ import com.willowtree.vocable.databinding.FragmentEditCategoriesBinding import com.willowtree.vocable.presets.Category import com.willowtree.vocable.utils.VocableFragmentStateAdapter import kotlinx.coroutines.launch -import org.koin.androidx.viewmodel.ViewModelOwner -import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.activityViewModel import kotlin.math.min class EditCategoriesFragment : BaseFragment() { @@ -27,9 +26,7 @@ class EditCategoriesFragment : BaseFragment() { FragmentEditCategoriesBinding::inflate private lateinit var categoriesAdapter: CategoriesPagerAdapter - private val editCategoriesViewModel: EditCategoriesViewModel by viewModel(owner = { - ViewModelOwner.from(requireActivity()) - }) + private val editCategoriesViewModel: EditCategoriesViewModel by activityViewModel() private val allViews = mutableListOf() private var maxEditCategories = 1 diff --git a/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesListFragment.kt b/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesListFragment.kt index 155df677..e056caf2 100644 --- a/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesListFragment.kt +++ b/app/src/main/java/com/willowtree/vocable/settings/EditCategoriesListFragment.kt @@ -17,8 +17,7 @@ import com.willowtree.vocable.presets.Category import com.willowtree.vocable.utils.locale.LocalizedResourceUtility import kotlinx.coroutines.launch import org.koin.android.ext.android.inject -import org.koin.androidx.viewmodel.ViewModelOwner -import org.koin.androidx.viewmodel.ext.android.viewModel +import org.koin.androidx.viewmodel.ext.android.activityViewModel class EditCategoriesListFragment : BaseFragment() { @@ -41,9 +40,7 @@ class EditCategoriesListFragment : BaseFragment = FragmentEditCategoriesListBinding::inflate - private val editCategoriesViewModel: EditCategoriesViewModel by viewModel(owner = { - ViewModelOwner.from(requireActivity()) - }) + private val editCategoriesViewModel: EditCategoriesViewModel by activityViewModel() private var maxEditCategories = 1 private var startPosition = 0 diff --git a/app/src/main/java/com/willowtree/vocable/settings/EditCategoryPhrasesFragment.kt b/app/src/main/java/com/willowtree/vocable/settings/EditCategoryPhrasesFragment.kt index fe855c28..00aafafe 100644 --- a/app/src/main/java/com/willowtree/vocable/settings/EditCategoryPhrasesFragment.kt +++ b/app/src/main/java/com/willowtree/vocable/settings/EditCategoryPhrasesFragment.kt @@ -18,7 +18,6 @@ import com.willowtree.vocable.presets.Phrase import com.willowtree.vocable.presets.PresetCategories import com.willowtree.vocable.settings.customcategories.CustomCategoryPhraseListFragment import com.willowtree.vocable.utils.VocableFragmentStateAdapter -import org.koin.androidx.viewmodel.ViewModelOwner import org.koin.androidx.viewmodel.ext.android.viewModel class EditCategoryPhrasesFragment : BaseFragment() { @@ -27,9 +26,7 @@ class EditCategoryPhrasesFragment : BaseFragment = FragmentEditCategoryPhrasesBinding::inflate - private val editCategoriesViewModel: EditCategoryPhrasesViewModel by viewModel(owner = { - ViewModelOwner.from(requireActivity()) - }) + private val editCategoriesViewModel: EditCategoryPhrasesViewModel by viewModel() private var maxPhrases = 1 private lateinit var phrasesAdapter: PhrasesPagerAdapter @@ -116,10 +113,6 @@ class EditCategoryPhrasesFragment : BaseFragment>() - val categoryPhraseList: LiveData> = liveCategoryPhraseList +) : ViewModel() { + + val categoryPhraseList: LiveData> = phrasesUseCase.getPhrasesForCategoryFlow(savedStateHandle.get("category")!!.categoryId) + .asLiveData() fun getCategoryName(category: Category): String { return localizedResourceUtility.getTextFromCategory(category) } - fun fetchCategoryPhrases(category: Category) { + fun deletePhraseFromCategory(phrase: Phrase) { viewModelScope.launch { - val phrasesForCategory = phrasesUseCase.getPhrasesForCategory(category.categoryId) - .sortedBy { it.sortOrder } - liveCategoryPhraseList.postValue(phrasesForCategory) - } - } - - fun deletePhraseFromCategory(phrase: Phrase, category: Category) { - viewModelScope.launch { - phrasesUseCase.deletePhrase(phrase.phraseId) - - // Refresh phrase list - fetchCategoryPhrases(category) } } } \ No newline at end of file diff --git a/app/src/main/java/com/willowtree/vocable/settings/customcategories/CustomCategoryPhraseListFragment.kt b/app/src/main/java/com/willowtree/vocable/settings/customcategories/CustomCategoryPhraseListFragment.kt index d20f7141..00bd5231 100644 --- a/app/src/main/java/com/willowtree/vocable/settings/customcategories/CustomCategoryPhraseListFragment.kt +++ b/app/src/main/java/com/willowtree/vocable/settings/customcategories/CustomCategoryPhraseListFragment.kt @@ -16,7 +16,6 @@ import com.willowtree.vocable.settings.EditCategoryPhrasesFragmentDirections import com.willowtree.vocable.settings.EditCategoryPhrasesViewModel import com.willowtree.vocable.settings.customcategories.adapter.CustomCategoryPhraseAdapter import com.willowtree.vocable.utils.ItemOffsetDecoration -import org.koin.androidx.viewmodel.ViewModelOwner import org.koin.androidx.viewmodel.ext.android.viewModel class CustomCategoryPhraseListFragment : BaseFragment() { @@ -35,9 +34,7 @@ class CustomCategoryPhraseListFragment : BaseFragment @@ -91,7 +88,7 @@ class CustomCategoryPhraseListFragment : BaseFragment> { + TODO("Not yet implemented") + } + override suspend fun updatePhraseLastSpokenTime(phraseId: String) { error("Not implemented") } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ff301ff2..68139c9b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,12 +6,14 @@ safe-args = "2.6.0" google-services = "4.3.15" crashlytics = "2.8.1" androidx-test = "1.5.0" +koin = "3.5.6" [libraries] turbine = { group = "app.cash.turbine", name = "turbine", version.ref = "turbine" } android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "agp" } kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" } androidx-test-core = { group = "androidx.test", name = "core", version.ref = "androidx-test"} +koin-android = { group = "io.insert-koin", name = "koin-android", version.ref = "koin" } [plugins] androidApplication = { id = "com.android.application", version.ref = "agp" }