Skip to content

Commit dfad138

Browse files
authored
Feature/add catalog favorites screen (#40)
* feat(core-database): Updated catalog favorites dao and local datasource * feat(mobile-app): Added catalog favorites default ui screen * feat(mobile-app): Added catalog favorites di module definition * feat(mobile-app): Added catalog favorites ui parts * feat(mobile-app): Added catalog favorites ui slots * feat(mobile-app): Added catalog favorites xml resources * feat(mobile-app): Renamed old files * feat(mobile-app): Updated catalog favorites ui route definition * feat(mobile-app): Updated fake catalog favorites local data source features * feat(mobile-app): Updated fake catalog favorites ui route, ui state, viewmodel and repository
1 parent a85d2d0 commit dfad138

File tree

24 files changed

+737
-49
lines changed

24 files changed

+737
-49
lines changed

apps/mobile-app/src/main/kotlin/dev/marlonlom/apps/cappajv/di/data_module.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import dev.marlonlom.apps.cappajv.core.database.datasource.LocalDataSource
1111
import dev.marlonlom.apps.cappajv.core.database.datasource.LocalDataSourceImpl
1212
import dev.marlonlom.apps.cappajv.core.preferences.UserPreferencesRepository
1313
import dev.marlonlom.apps.cappajv.dataStore
14+
import dev.marlonlom.apps.cappajv.features.catalog_favorites.CatalogFavoritesRepository
1415
import dev.marlonlom.apps.cappajv.features.catalog_list.CatalogListRepository
1516
import dev.marlonlom.apps.cappajv.features.catalog_search.CatalogSearchRepository
1617
import org.koin.android.ext.koin.androidContext
@@ -37,6 +38,11 @@ val dataModule = module {
3738
catalogDataService = get(),
3839
)
3940
}
41+
single<CatalogFavoritesRepository> {
42+
CatalogFavoritesRepository(
43+
localDataSource = get(),
44+
)
45+
}
4046
single<CatalogSearchRepository> {
4147
CatalogSearchRepository(
4248
localDataSource = get(),

apps/mobile-app/src/main/kotlin/dev/marlonlom/apps/cappajv/di/viewmodels_module.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package dev.marlonlom.apps.cappajv.di
77

88
import dev.marlonlom.apps.cappajv.features.catalog_detail.CatalogDetailViewModel
9+
import dev.marlonlom.apps.cappajv.features.catalog_favorites.CatalogFavoritesViewModel
910
import dev.marlonlom.apps.cappajv.features.catalog_list.CatalogListViewModel
1011
import dev.marlonlom.apps.cappajv.features.catalog_search.CatalogSearchViewModel
1112
import dev.marlonlom.apps.cappajv.features.settings.SettingsViewModel
@@ -15,6 +16,7 @@ import org.koin.dsl.module
1516
val viewModelsModule = module {
1617
includes(dataModule)
1718
viewModelOf(::CatalogListViewModel)
19+
viewModelOf(::CatalogFavoritesViewModel)
1820
viewModelOf(::CatalogSearchViewModel)
1921
viewModelOf(::CatalogDetailViewModel)
2022
viewModelOf(::SettingsViewModel)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright 2024 Marlonlom
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dev.marlonlom.apps.cappajv.features.catalog_favorites
7+
8+
import dev.marlonlom.apps.cappajv.core.database.datasource.LocalDataSource
9+
import dev.marlonlom.apps.cappajv.core.database.entities.CatalogItemTuple
10+
import kotlinx.coroutines.flow.Flow
11+
import kotlinx.coroutines.flow.map
12+
13+
/**
14+
* Catalog favorites repository.
15+
*
16+
* @author marlonlom
17+
*
18+
* @property localDataSource Local data source.
19+
*/
20+
class CatalogFavoritesRepository(
21+
private val localDataSource: LocalDataSource,
22+
) {
23+
24+
/** Returns Favorite catalog items list as flow. */
25+
val favoritesListFlow: Flow<List<CatalogItemTuple>> = localDataSource.getFavorites().map { f ->
26+
f.map {
27+
CatalogItemTuple(
28+
it.id,
29+
it.title,
30+
it.picture,
31+
it.category,
32+
it.samplePunctuation,
33+
it.punctuationsCount
34+
)
35+
}
36+
}
37+
38+
/**
39+
* Deletes a catalog item marked as favorite, using its provided id.
40+
*
41+
* @param catalogId Catalog item id.
42+
*/
43+
suspend fun deleteFavorite(catalogId: Long) = localDataSource.deleteFavorite(catalogId)
44+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2024 Marlonlom
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dev.marlonlom.apps.cappajv.features.catalog_favorites
7+
8+
import androidx.compose.foundation.ExperimentalFoundationApi
9+
import androidx.compose.runtime.Composable
10+
import androidx.compose.runtime.getValue
11+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
12+
import dev.marlonlom.apps.cappajv.features.catalog_favorites.screens.CatalogFavoritesRouteScreen
13+
import dev.marlonlom.apps.cappajv.ui.main.CappajvAppState
14+
import org.koin.androidx.compose.koinViewModel
15+
import timber.log.Timber
16+
17+
/**
18+
* Catalog favorites route composable ui.
19+
*
20+
* @author marlonlom
21+
*
22+
* @param appState Application ui state.
23+
* @param viewModel Catalog favorites viewmodel.
24+
*/
25+
@ExperimentalFoundationApi
26+
@Composable
27+
fun CatalogFavoritesRoute(
28+
appState: CappajvAppState,
29+
viewModel: CatalogFavoritesViewModel = koinViewModel(),
30+
) {
31+
val favoritesListState by viewModel.favoritesListState.collectAsStateWithLifecycle()
32+
CatalogFavoritesRouteScreen(
33+
appState = appState,
34+
favoritesListState = favoritesListState,
35+
onFavoriteItemClicked = { catalogId, isRouting ->
36+
Timber.d("[CatalogFavoritesRoute] clicked item[$catalogId], isRouting=$isRouting ")
37+
},
38+
onFavoriteItemRemoved = viewModel::deleteFavorite,
39+
)
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
* Copyright 2024 Marlonlom
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dev.marlonlom.apps.cappajv.features.catalog_favorites
7+
8+
import dev.marlonlom.apps.cappajv.core.database.entities.CatalogItemTuple
9+
10+
/**
11+
* Catalog favorites ui state.
12+
*
13+
* @author marlonlom
14+
*/
15+
sealed class CatalogFavoritesUiState {
16+
17+
/**
18+
* Empty results phase of catalog favorites ui state.
19+
*
20+
* @author marlonlom
21+
*/
22+
data object Empty : CatalogFavoritesUiState()
23+
24+
/**
25+
* Fetching phase of catalog favorites ui state.
26+
*
27+
* @author marlonlom
28+
*/
29+
data object Fetching : CatalogFavoritesUiState()
30+
31+
/**
32+
* Success result phase of catalog favorites ui state.
33+
*
34+
* @author marlonlom
35+
*
36+
* @property results
37+
*/
38+
data class Success(val results: List<CatalogItemTuple>) : CatalogFavoritesUiState()
39+
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright 2024 Marlonlom
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dev.marlonlom.apps.cappajv.features.catalog_favorites
7+
8+
import androidx.lifecycle.ViewModel
9+
import androidx.lifecycle.viewModelScope
10+
import dev.marlonlom.apps.cappajv.features.catalog_favorites.CatalogFavoritesUiState.Empty
11+
import dev.marlonlom.apps.cappajv.features.catalog_favorites.CatalogFavoritesUiState.Fetching
12+
import dev.marlonlom.apps.cappajv.features.catalog_favorites.CatalogFavoritesUiState.Success
13+
import kotlinx.coroutines.flow.MutableStateFlow
14+
import kotlinx.coroutines.flow.SharingStarted
15+
import kotlinx.coroutines.flow.stateIn
16+
import kotlinx.coroutines.flow.update
17+
import kotlinx.coroutines.launch
18+
19+
class CatalogFavoritesViewModel(
20+
private val repository: CatalogFavoritesRepository
21+
) : ViewModel() {
22+
23+
private val _favoritesListState = MutableStateFlow<CatalogFavoritesUiState>(Empty)
24+
val favoritesListState = _favoritesListState.stateIn(
25+
scope = viewModelScope,
26+
started = SharingStarted.Eagerly,
27+
initialValue = Empty
28+
)
29+
30+
init {
31+
this.fetchAllFavorites()
32+
}
33+
34+
private fun fetchAllFavorites() {
35+
viewModelScope.launch {
36+
_favoritesListState.update { Fetching }
37+
repository.favoritesListFlow.collect { list ->
38+
_favoritesListState.update { if (list.isEmpty()) Empty else Success(list) }
39+
}
40+
}
41+
}
42+
43+
fun deleteFavorite(catalogId: Long) {
44+
viewModelScope.launch {
45+
repository.deleteFavorite(catalogId)
46+
}
47+
}
48+
}

apps/mobile-app/src/main/kotlin/dev/marlonlom/apps/cappajv/features/catalog_favorites/FavoriteProductsRoute.kt

Lines changed: 0 additions & 42 deletions
This file was deleted.

0 commit comments

Comments
 (0)