Skip to content

Commit 0848ae8

Browse files
author
robertmurithi
committed
clean up on task and tasks categories
1 parent c13a7a6 commit 0848ae8

File tree

19 files changed

+213
-103
lines changed

19 files changed

+213
-103
lines changed

app/src/main/java/dev/robert/composetodo/navigation/MainApp.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ fun MainApp(
8787
var selectedIndex by remember {
8888
mutableIntStateOf(0)
8989
}
90-
Timber.d("User Object: $userObject")
9190

9291
// TODO: FIX THIS/ OR FIND BETTER APPROACH.. it's always reseting to 0 when user navigates back
9392
LaunchedEffect(currentDestination) {

core/database/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ android {
4343
}
4444

4545
dependencies {
46-
46+
implementation(project(path = ":core:design-system"))
4747
implementation(libs.androidx.core.ktx)
4848
// room
4949
implementation(libs.androidx.room.runtime)

core/database/src/main/java/dev/robert/database/ConstUtils.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ package dev.robert.database
1717

1818
object ConstUtils {
1919
const val TODO_TABLE_NAME = "todos"
20+
const val TODO_TASK_CATEGORY_TABLE_NAME = "task_categories"
2021
const val TODO_DATABASE = "todos_database.db"
2122
}

core/database/src/main/java/dev/robert/database/data/todo/TodoDatabase.kt renamed to core/database/src/main/java/dev/robert/database/data/TodoDatabase.kt

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package dev.robert.database.data.todo
16+
package dev.robert.database.data
1717

1818
import androidx.room.Database
1919
import androidx.room.RoomDatabase
2020
import androidx.room.TypeConverters
2121
import dev.robert.database.TasksTypeConverter
22+
import dev.robert.database.data.categories.CategoriesDao
23+
import dev.robert.database.data.categories.CategoryEntity
24+
import dev.robert.database.data.todo.TodoDao
25+
import dev.robert.database.data.todo.TodoEntity
2226

2327
@Database(
2428
exportSchema = false,
2529
entities = [
2630
TodoEntity::class,
31+
CategoryEntity::class
2732
],
2833
version = 4,
2934
)
3035
@TypeConverters(TasksTypeConverter::class)
3136
abstract class TodoDatabase : RoomDatabase() {
32-
abstract val dao: TodoDao
37+
abstract val tasksDao: TodoDao
38+
abstract val categoryDao: CategoriesDao
3339
}

core/database/src/main/java/dev/robert/database/data/todo/TodoEntity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,6 @@ data class TodoEntity(
3737

3838
data class TaskCategoryModelEntity(
3939
val name: String,
40+
val color: String? = null,
41+
val icon: Int? = null
4042
)

core/database/src/main/java/dev/robert/database/domain/DatabaseModule.kt

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,22 @@ package dev.robert.database.domain
1717

1818
import android.content.Context
1919
import androidx.room.Room
20+
import androidx.room.RoomDatabase
21+
import androidx.sqlite.db.SupportSQLiteDatabase
2022
import com.google.gson.Gson
2123
import dagger.Module
2224
import dagger.Provides
2325
import dagger.hilt.InstallIn
2426
import dagger.hilt.android.qualifiers.ApplicationContext
2527
import dagger.hilt.components.SingletonComponent
2628
import dev.robert.database.ConstUtils.TODO_DATABASE
29+
import dev.robert.design_system.R
2730
import dev.robert.database.TasksTypeConverter
28-
import dev.robert.database.data.todo.TodoDatabase
31+
import dev.robert.database.data.TodoDatabase
32+
import dev.robert.database.data.categories.CategoryEntity
33+
import kotlinx.coroutines.CoroutineScope
34+
import kotlinx.coroutines.Dispatchers
35+
import kotlinx.coroutines.launch
2936
import javax.inject.Singleton
3037

3138
@Module
@@ -41,7 +48,13 @@ object DatabaseModule {
4148
Provides
4249
Singleton
4350
]
44-
fun provideTodoDao(db: TodoDatabase) = db.dao
51+
fun provideTodoDao(db: TodoDatabase) = db.tasksDao
52+
53+
@[
54+
Provides
55+
Singleton
56+
]
57+
fun provideCategoryDao(db: TodoDatabase) = db.categoryDao
4558

4659
@[
4760
Provides
@@ -63,7 +76,29 @@ object DatabaseModule {
6376
TODO_DATABASE,
6477
).addTypeConverter(converter)
6578
.fallbackToDestructiveMigration()
66-
.allowMainThreadQueries()
79+
.addCallback(object : RoomDatabase.Callback() {
80+
override fun onCreate(db: SupportSQLiteDatabase) {
81+
super.onCreate(db)
82+
// db.execSQL("INSERT INTO task_categories (name, color, icon) VALUES ('Work', '#FF5733', '')")
83+
// db.execSQL("INSERT INTO task_categories (name, color, icon) VALUES ('Personal', '#33FF57', '')")
84+
// db.execSQL("INSERT INTO task_categories (name, color, icon) VALUES ('Shopping', '#3357FF', '')")
85+
// db.execSQL("INSERT INTO task_categories (name, color, icon) VALUES ('Health', '#FF33F6', '')")
86+
// db.execSQL("INSERT INTO task_categories (name, color, icon) VALUES ('Miscellaneous', '#33FFF6', '')")
87+
CoroutineScope(Dispatchers.IO).launch {
88+
provideCategoryDao(provideTodoDatabase(context, converter))
89+
.insertAll(getInitialCategories())
90+
}
91+
}
92+
})
6793
.build()
6894
}
95+
96+
97+
private fun getInitialCategories(): List<CategoryEntity> = listOf(
98+
CategoryEntity(name = "Work", color = "#FF5733", icon = R.drawable.ic_work_outline),
99+
CategoryEntity(name = "Personal", color = "#33FF57", icon = R.drawable.ic_personal),
100+
CategoryEntity(name = "Shopping", color = "#3357FF", icon = R.drawable.ic_shopping),
101+
CategoryEntity(name = "Health", color = "#FF33F6", icon = R.drawable.ic_health_safety),
102+
CategoryEntity(name = "Miscellaneous", color = "#33FFF6", icon = R.drawable.ic_miscellaneous_services)
103+
)
69104
}

feature/tasks/src/main/java/dev/robert/tasks/data/datasource/LocalDataSource.kt renamed to feature/tasks/src/main/java/dev/robert/tasks/data/datasource/TaskLocalDataSource.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import javax.inject.Inject
2323
import kotlinx.coroutines.flow.Flow
2424
import kotlinx.coroutines.flow.map
2525

26-
interface LocalDataSource {
26+
interface TaskLocalDataSource {
2727
val tasks: Flow<List<TodoModel>>
2828
fun getTaskById(id: Int): Flow<TodoModel>
2929
suspend fun saveTask(task: TodoModel): Result<Boolean>
@@ -34,7 +34,7 @@ interface LocalDataSource {
3434
suspend fun updateTask(task: TodoModel): Boolean
3535
}
3636

37-
class LocalDataStoreImpl @Inject constructor(private val taskDao: TodoDao) : LocalDataSource {
37+
class TaskLocalDataStoreImpl @Inject constructor(private val taskDao: TodoDao) : TaskLocalDataSource {
3838

3939
override val tasks: Flow<List<TodoModel>>
4040
get() = try {

feature/tasks/src/main/java/dev/robert/tasks/data/mappers/TaskModelMapper.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package dev.robert.tasks.data.mappers
1717

18+
import dev.robert.database.data.categories.CategoryEntity
1819
import dev.robert.database.data.todo.TaskCategoryModelEntity
1920
import dev.robert.database.data.todo.TodoEntity
2021
import dev.robert.tasks.data.model.TaskCategoryModel
@@ -36,10 +37,12 @@ fun TodoEntity.toTodoModel() = TodoModel(
3637

3738
fun TaskCategoryModelEntity.toDomain() = TaskCategoryModel(
3839
name = name,
40+
icon = icon
3941
)
4042

4143
fun TaskCategoryModel.toEntity() = TaskCategoryModelEntity(
4244
name = name,
45+
icon = icon
4346
)
4447

4548
fun TodoModel.toEntity() = TodoEntity(
@@ -80,8 +83,24 @@ fun TaskItem.toTodoModel() = TodoModel(
8083

8184
fun TaskCategoryModel.toDomain() = TaskCategory(
8285
name = name,
86+
color = color,
87+
icon = icon,
8388
)
8489

8590
fun TaskCategory.toModel() = TaskCategoryModel(
8691
name = name,
92+
color = color ?: "",
93+
icon = icon,
94+
)
95+
96+
fun CategoryEntity.toDomain() = TaskCategory(
97+
name = name,
98+
color = color,
99+
icon = icon,
100+
)
101+
102+
fun TaskCategory.toEntity() = CategoryEntity(
103+
name = name,
104+
color = color ?: "",
105+
icon = icon ?: 0,
87106
)

feature/tasks/src/main/java/dev/robert/tasks/data/model/TodoModel.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ data class TodoModel(
2929

3030
data class TaskCategoryModel(
3131
val name: String = "",
32+
val color: String? = null,
33+
val icon: Int? = null
3234
)

feature/tasks/src/main/java/dev/robert/tasks/data/repo/TasksRepositoryImpl.kt

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ package dev.robert.tasks.data.repo
1717

1818
import com.google.firebase.firestore.FirebaseFirestore
1919
import dev.robert.datastore.data.TodoAppPreferences
20-
import dev.robert.tasks.data.datasource.LocalDataSource
20+
import dev.robert.tasks.data.datasource.TaskLocalDataSource
2121
import dev.robert.tasks.data.datasource.RemoteDataSource
2222
import dev.robert.tasks.data.mappers.toTodoItem
2323
import dev.robert.tasks.data.mappers.toTodoModel
@@ -36,7 +36,7 @@ import kotlinx.coroutines.tasks.await
3636

3737
@Singleton
3838
class TasksRepositoryImpl @Inject constructor(
39-
private val localDataSource: LocalDataSource,
39+
private val taskLocalDataSource: TaskLocalDataSource,
4040
private val remoteDataSource: RemoteDataSource,
4141
private val database: FirebaseFirestore,
4242
private val preferences: TodoAppPreferences,
@@ -52,35 +52,50 @@ class TasksRepositoryImpl @Inject constructor(
5252
}
5353
if (fetchRemote) {
5454
val remoteTasks = remoteDataSource.getTasks(uid).map { it.toTodoItem() }
55-
localDataSource.clear()
55+
taskLocalDataSource.clear()
5656
remoteTasks.forEach { saveTask(it) }
5757
}
58-
emitAll(localDataSource.tasks.map { list -> list.map { it.toTodoItem() } })
58+
emitAll(taskLocalDataSource.tasks.map { list -> list.map { it.toTodoItem() } })
5959
}
6060
}
6161

62+
fun fetchTasks(fetchRemote: Boolean): Flow<List<TaskItem>> = flow {
63+
val uid = preferences.userData.firstOrNull()?.id
64+
if (uid.isNullOrEmpty()) {
65+
emit(emptyList())
66+
return@flow
67+
}
68+
if (fetchRemote) {
69+
val remoteTasks = remoteDataSource.getTasks(uid).map { it.toTodoItem() }
70+
taskLocalDataSource.clear()
71+
remoteTasks.forEach { saveTask(it) }
72+
}
73+
emitAll(taskLocalDataSource.tasks.map { list -> list.map { it.toTodoItem() } })
74+
}
75+
76+
6277
override val task: (taskId: Int) -> Flow<TaskItem>
6378
get() = { taskId ->
64-
localDataSource.getTaskById(taskId).map {
79+
taskLocalDataSource.getTaskById(taskId).map {
6580
it.toTodoItem()
6681
}
6782
}
6883

6984
override val searchTasks: (query: String) -> Flow<List<TaskItem>>
7085
get() = { query ->
71-
localDataSource.tasks.map { list ->
86+
taskLocalDataSource.tasks.map { list ->
7287
list.filter { it.name.contains(query, ignoreCase = true) }
7388
.map { it.toTodoItem() }
7489
}
7590
}
7691

77-
override suspend fun saveTask(task: TaskItem): Result<Boolean> = localDataSource.saveTask(task.toTodoModel())
92+
override suspend fun saveTask(task: TaskItem): Result<Boolean> = taskLocalDataSource.saveTask(task.toTodoModel())
7893

7994
override suspend fun deleteTask(taskId: Int): Result<Boolean> {
8095
return try {
8196
val uid = preferences.userData.firstOrNull()?.id
8297
?: return Result.failure(Exception("User not authenticated"))
83-
localDataSource.deleteTask(taskId)
98+
taskLocalDataSource.deleteTask(taskId)
8499
remoteDataSource.deleteTask(uid, taskId)
85100
Result.success(true)
86101
} catch (e: Exception) {
@@ -95,7 +110,7 @@ class TasksRepositoryImpl @Inject constructor(
95110
emit(false)
96111
return@flow
97112
}
98-
val updated = localDataSource.updateTask(task.toTodoModel())
113+
val updated = taskLocalDataSource.updateTask(task.toTodoModel())
99114
emit(updated)
100115
}
101116
}
@@ -113,7 +128,7 @@ class TasksRepositoryImpl @Inject constructor(
113128
.document(taskId.toString())
114129
.set(this.toTodoModel())
115130
.await()
116-
localDataSource.setSynced(taskId)
131+
taskLocalDataSource.setSynced(taskId)
117132
}
118133
}
119134
Result.success(true)
@@ -124,7 +139,7 @@ class TasksRepositoryImpl @Inject constructor(
124139
}
125140

126141
override suspend fun completeTask(taskId: Int, completionDate: String): Result<Boolean> = try {
127-
localDataSource.completeTask(taskId = taskId, completionDate = completionDate)
142+
taskLocalDataSource.completeTask(taskId = taskId, completionDate = completionDate)
128143
Result.success(true)
129144
} catch (e: Exception) {
130145
Result.failure(e)

0 commit comments

Comments
 (0)