Skip to content

Commit 7ff19d7

Browse files
committed
- adds category entity (kinda)
1 parent 0486459 commit 7ff19d7

File tree

11 files changed

+259
-62
lines changed

11 files changed

+259
-62
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package cloud.pablos.overload.data
2+
3+
import android.content.Context
4+
import androidx.room.Database
5+
import androidx.room.Room
6+
import androidx.room.RoomDatabase
7+
import cloud.pablos.overload.data.category.Category
8+
import cloud.pablos.overload.data.category.CategoryDao
9+
import cloud.pablos.overload.data.item.Item
10+
import cloud.pablos.overload.data.item.ItemDao
11+
12+
@Database(entities = [Category::class, Item::class], version = 1)
13+
abstract class OverloadDatabase : RoomDatabase() {
14+
abstract fun categoryDao(): CategoryDao
15+
16+
abstract fun itemDao(): ItemDao
17+
18+
companion object {
19+
const val DATABASE_NAME = "overload"
20+
21+
@Volatile private var instance: OverloadDatabase? = null
22+
23+
fun getInstance(context: Context): OverloadDatabase =
24+
instance
25+
?: synchronized(this) {
26+
instance ?: buildDatabase(context).also { instance = it }
27+
}
28+
29+
private fun buildDatabase(context: Context) =
30+
Room.databaseBuilder(
31+
context.applicationContext,
32+
OverloadDatabase::class.java,
33+
DATABASE_NAME,
34+
).build()
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package cloud.pablos.overload.data.category
2+
3+
import androidx.room.Entity
4+
import androidx.room.PrimaryKey
5+
6+
@Entity(tableName = "categories")
7+
data class Category(
8+
@PrimaryKey(autoGenerate = true) val id: Int = 0,
9+
val name: String,
10+
// val color: Color,
11+
// val default: Boolean,
12+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package cloud.pablos.overload.data.category
2+
3+
import androidx.room.Dao
4+
import androidx.room.Delete
5+
import androidx.room.Query
6+
import androidx.room.Upsert
7+
import kotlinx.coroutines.flow.Flow
8+
9+
@Dao
10+
interface CategoryDao {
11+
@Upsert
12+
suspend fun upsertCategory(category: Category)
13+
14+
// @Upsert
15+
// suspend fun upsertCategories(items: List<Category>)
16+
17+
@Delete
18+
suspend fun deleteCategory(category: Category)
19+
20+
// @Delete
21+
// suspend fun deleteCategories(items: List<Category>)
22+
23+
@Query("SELECT * FROM categories")
24+
fun getAllCategories(): Flow<List<Category>>
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package cloud.pablos.overload.data.category
2+
3+
sealed interface CategoryEvent {
4+
data object SaveCategory : CategoryEvent
5+
6+
data class SetId(val id: Int) : CategoryEvent
7+
8+
data class SetName(val name: String) : CategoryEvent
9+
10+
// data class SetColor(val color: Color) : CategoryEvent
11+
12+
// data class SetDefault(val default: Boolean) : CategoryEvent
13+
14+
data class DeleteCategory(val category: Category) : CategoryEvent
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package cloud.pablos.overload.data.category
2+
3+
data class CategoryState(
4+
val categories: List<Category> = emptyList(),
5+
val id: Int = 0,
6+
val name: String = "Default",
7+
// val color: Color = Color.Unspecified,
8+
// val default: Boolean = true,
9+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package cloud.pablos.overload.data.category
2+
3+
import androidx.lifecycle.ViewModel
4+
import androidx.lifecycle.viewModelScope
5+
import kotlinx.coroutines.flow.MutableStateFlow
6+
import kotlinx.coroutines.flow.SharingStarted
7+
import kotlinx.coroutines.flow.combine
8+
import kotlinx.coroutines.flow.stateIn
9+
import kotlinx.coroutines.flow.update
10+
import kotlinx.coroutines.launch
11+
12+
class CategoryViewModel(
13+
private val dao: CategoryDao,
14+
) : ViewModel() {
15+
private val _categories =
16+
dao.getAllCategories().stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
17+
private val _state = MutableStateFlow(CategoryState())
18+
val state =
19+
combine(_state, _categories) { state, categories ->
20+
state.copy(
21+
categories = categories,
22+
)
23+
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), CategoryState())
24+
25+
fun onEvent(event: CategoryEvent) {
26+
when (event) {
27+
is CategoryEvent.DeleteCategory -> {
28+
viewModelScope.launch {
29+
dao.deleteCategory(event.category)
30+
31+
/*_state.update {
32+
it.copy(
33+
// TODO: If current category, then switch to default
34+
)
35+
}*/
36+
}
37+
}
38+
39+
CategoryEvent.SaveCategory -> {
40+
val id = _state.value.id
41+
val name = _state.value.name
42+
// val color = _state.value.color
43+
// val default = _state.value.default
44+
45+
val category =
46+
Category(
47+
id = id,
48+
name = name,
49+
// color = color,
50+
// default = default,
51+
)
52+
53+
viewModelScope.launch {
54+
dao.upsertCategory(category)
55+
}
56+
57+
_state.update {
58+
it.copy(
59+
id = 0,
60+
name = "",
61+
// color = Color.Unspecified,
62+
// default = false,
63+
)
64+
}
65+
}
66+
67+
// is CategoryEvent.SetColor -> {
68+
// _state.update {
69+
// it.copy(
70+
// color = event.color,
71+
// )
72+
// }
73+
// }
74+
75+
// is CategoryEvent.SetDefault -> {
76+
// _state.update {
77+
// it.copy(
78+
// default = event.default,
79+
// )
80+
// }
81+
// }
82+
83+
is CategoryEvent.SetId -> {
84+
_state.update {
85+
it.copy(
86+
id = event.id,
87+
)
88+
}
89+
}
90+
91+
is CategoryEvent.SetName -> {
92+
_state.update {
93+
it.copy(
94+
name = event.name,
95+
)
96+
}
97+
}
98+
}
99+
}
100+
}

app/src/main/java/cloud/pablos/overload/data/item/ItemDatabase.kt

-30
This file was deleted.

app/src/main/java/cloud/pablos/overload/ui/MainActivity.kt

+24-8
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ import androidx.lifecycle.ViewModelProvider
2121
import androidx.lifecycle.lifecycleScope
2222
import androidx.room.Room
2323
import cloud.pablos.overload.R
24-
import cloud.pablos.overload.data.item.ItemDatabase
24+
import cloud.pablos.overload.data.OverloadDatabase
25+
import cloud.pablos.overload.data.category.CategoryViewModel
2526
import cloud.pablos.overload.data.item.ItemViewModel
2627
import cloud.pablos.overload.ui.tabs.configurations.handleIntent
2728
import cloud.pablos.overload.ui.tabs.configurations.importJsonFile
@@ -34,12 +35,22 @@ class MainActivity : ComponentActivity() {
3435
private val db by lazy {
3536
Room.databaseBuilder(
3637
applicationContext,
37-
ItemDatabase::class.java,
38-
"items",
38+
OverloadDatabase::class.java,
39+
"overload",
3940
).build()
4041
}
4142

42-
private val viewModel by viewModels<ItemViewModel>(
43+
private val categoryViewModel by viewModels<CategoryViewModel>(
44+
factoryProducer = {
45+
object : ViewModelProvider.Factory {
46+
override fun <T : ViewModel> create(modelClass: Class<T>): T {
47+
return CategoryViewModel(db.categoryDao()) as T
48+
}
49+
}
50+
},
51+
)
52+
53+
private val itemViewModel by viewModels<ItemViewModel>(
4354
factoryProducer = {
4455
object : ViewModelProvider.Factory {
4556
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@@ -85,14 +96,19 @@ class MainActivity : ComponentActivity() {
8596
val windowSize = calculateWindowSizeClass(this)
8697
val displayFeatures = calculateDisplayFeatures(this)
8798

88-
val state by viewModel.state.collectAsState()
89-
val onEvent = viewModel::onEvent
99+
val categoryState by categoryViewModel.state.collectAsState()
100+
val categoryEvent = categoryViewModel::onEvent
101+
102+
val itemState by itemViewModel.state.collectAsState()
103+
val itemEvent = itemViewModel::onEvent
90104

91105
OverloadApp(
92106
windowSize = windowSize,
93107
displayFeatures = displayFeatures,
94-
state = state,
95-
onEvent = onEvent,
108+
categoryState = categoryState,
109+
categoryEvent = categoryEvent,
110+
itemState = itemState,
111+
itemEvent = itemEvent,
96112
filePickerLauncher = filePickerLauncher,
97113
)
98114
}

app/src/main/java/cloud/pablos/overload/ui/OverloadApp.kt

+24-4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import androidx.navigation.compose.currentBackStackEntryAsState
3636
import androidx.navigation.compose.rememberNavController
3737
import androidx.window.layout.DisplayFeature
3838
import androidx.window.layout.FoldingFeature
39+
import cloud.pablos.overload.data.category.CategoryEvent
40+
import cloud.pablos.overload.data.category.CategoryState
3941
import cloud.pablos.overload.data.item.ItemEvent
4042
import cloud.pablos.overload.data.item.ItemState
4143
import cloud.pablos.overload.ui.navigation.ModalNavigationDrawerContent
@@ -65,8 +67,10 @@ import kotlinx.coroutines.launch
6567
fun OverloadApp(
6668
windowSize: WindowSizeClass,
6769
displayFeatures: List<DisplayFeature>,
68-
state: ItemState,
69-
onEvent: (ItemEvent) -> Unit,
70+
categoryState: CategoryState,
71+
categoryEvent: (CategoryEvent) -> Unit,
72+
itemState: ItemState,
73+
itemEvent: (ItemEvent) -> Unit,
7074
filePickerLauncher: ActivityResultLauncher<Intent>,
7175
) {
7276
val navigationType: OverloadNavigationType
@@ -138,8 +142,10 @@ fun OverloadApp(
138142
navigationType = navigationType,
139143
contentType = contentType,
140144
navigationContentPosition = navigationContentPosition,
141-
state = state,
142-
onEvent = onEvent,
145+
categoryState = categoryState,
146+
categoryEvent = categoryEvent,
147+
state = itemState,
148+
onEvent = itemEvent,
143149
filePickerLauncher = filePickerLauncher,
144150
)
145151
}
@@ -150,6 +156,8 @@ private fun OverloadNavigationWrapper(
150156
navigationType: OverloadNavigationType,
151157
contentType: OverloadContentType,
152158
navigationContentPosition: OverloadNavigationContentPosition,
159+
categoryState: CategoryState,
160+
categoryEvent: (CategoryEvent) -> Unit,
153161
state: ItemState,
154162
onEvent: (ItemEvent) -> Unit,
155163
filePickerLauncher: ActivityResultLauncher<Intent>,
@@ -180,6 +188,8 @@ private fun OverloadNavigationWrapper(
180188
drawerState.open()
181189
}
182190
},
191+
categoryState = categoryState,
192+
categoryEvent = categoryEvent,
183193
state = state,
184194
onEvent = onEvent,
185195
filePickerLauncher = filePickerLauncher,
@@ -216,6 +226,8 @@ private fun OverloadNavigationWrapper(
216226
drawerState.open()
217227
}
218228
},
229+
categoryState = categoryState,
230+
categoryEvent = categoryEvent,
219231
state = state,
220232
onEvent = onEvent,
221233
filePickerLauncher = filePickerLauncher,
@@ -236,6 +248,8 @@ fun OverloadAppContent(
236248
selectedDestination: String,
237249
navigateToTopLevelDestination: (OverloadTopLevelDestination) -> Unit,
238250
onDrawerClicked: () -> Unit = {},
251+
categoryState: CategoryState,
252+
categoryEvent: (CategoryEvent) -> Unit,
239253
state: ItemState,
240254
onEvent: (ItemEvent) -> Unit,
241255
filePickerLauncher: ActivityResultLauncher<Intent>,
@@ -276,6 +290,8 @@ fun OverloadAppContent(
276290
navigationType = navigationType,
277291
contentType = contentType,
278292
navController = navController,
293+
categoryState = categoryState,
294+
categoryEvent = categoryEvent,
279295
state = state,
280296
onEvent = onEvent,
281297
filePickerLauncher = filePickerLauncher,
@@ -336,6 +352,8 @@ private fun OverloadNavHost(
336352
contentType: OverloadContentType,
337353
navController: NavHostController,
338354
modifier: Modifier = Modifier,
355+
categoryState: CategoryState,
356+
categoryEvent: (CategoryEvent) -> Unit,
339357
state: ItemState,
340358
onEvent: (ItemEvent) -> Unit,
341359
filePickerLauncher: ActivityResultLauncher<Intent>,
@@ -362,6 +380,8 @@ private fun OverloadNavHost(
362380
}
363381
composable(OverloadRoute.CATEGORY) {
364382
CategoryScreen(
383+
categoryState = categoryState,
384+
categoryEvent = categoryEvent,
365385
state = state,
366386
onEvent = onEvent,
367387
)

0 commit comments

Comments
 (0)