Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move to kotlinx coroutines #38

Merged
merged 4 commits into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .idea/.name

This file was deleted.

2 changes: 1 addition & 1 deletion .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
## License

```
Copyright 2022-2023 Felipe Joglar
Copyright 2022-2024 Felipe Joglar

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion apps/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ dependencies {
implementation(libs.precompose.viewmodel)

testImplementation(libs.junit)
testImplementation(libs.coroutines.test)
testImplementation(libs.kotlinx.coroutines.test)

debugImplementation(libs.androidx.compose.ui.tooling)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Felipe Joglar
* Copyright 2024 Felipe Joglar
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,8 +27,8 @@ import com.taskodoro.android.app.navigation.graphs.tasks.TASK_GRAPH_ROUTE
import com.taskodoro.android.app.navigation.graphs.tasks.navigateToTaskGraph
import com.taskodoro.android.app.navigation.graphs.tasks.taskGraph
import com.taskodoro.android.app.navigation.transitions.forwardBackwardNavTransition
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import moe.tlaster.precompose.PreComposeApp
import moe.tlaster.precompose.navigation.NavHost
import moe.tlaster.precompose.navigation.NavOptions
Expand All @@ -46,8 +46,7 @@ fun AppNavigation(
val navigator = rememberNavigator()
val scope = rememberCoroutineScope()

val isOnboarded = onboardingStore.isOnboarded().getOrThrow()

val isOnboarded = runBlocking { onboardingStore.isOnboarded().getOrThrow() }
val initialRoute = if (isOnboarded) TASK_GRAPH_ROUTE else ONBOARDING_GRAPH_ROUTE

NavHost(
Expand All @@ -58,7 +57,7 @@ fun AppNavigation(
) {
onboardingGraph(
onContinueClicked = {
flowOf(onboardingStore.setOnboarded()).launchIn(scope)
scope.launch { onboardingStore.setOnboarded() }

val options = NavOptions(popUpTo = PopUpTo.First())
navigator.navigateToTaskGraph(options)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ class TaskNewViewModelTest {
private class TaskNewUseCaseStub : TaskNewUseCase {
private var result: Result<Unit>? = null

override fun invoke(
override suspend fun invoke(
title: String,
description: String?,
dueDate: Long?,
Expand Down
29 changes: 16 additions & 13 deletions gradle/catalogs/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ detektGradlePlugin = "1.23.1"

desugar = "2.0.4"
activity-compose = "1.8.2"
androidx-activity = "1.8.2"
androidx-splashscreen = "1.0.1"
androidx-lifecycle = "2.6.2"
androidx-activity = "1.8.2"
androidx-splashscreen = "1.0.1"
androidx-lifecycle = "2.6.2"

coil = "2.5.0"

Expand All @@ -35,12 +35,12 @@ compose-compiler = "1.5.7"

precompose = "1.5.10"

coroutines = "1.7.3"

sqlDelight = "2.0.1"
datastore = "1.1.0-alpha07"

datetime = "0.4.1"
coroutines = "1.7.3"

junit = "4.13.2"

Expand Down Expand Up @@ -81,7 +81,10 @@ sqlDelight-jvm-driver = { module = "app.cash.sqldelight:sqlite-driver", version.
datastore = { module = "androidx.datastore:datastore-preferences-core", version.ref = "datastore" }

# kotlinx datetime - https://github.com/Kotlin/kotlinx-datetime
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime"}
kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" }

# kotlinx coroutines - https://github.com/Kotlin/kotlinx.coroutines
kotlinx-coroutines = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "coroutines" }

# JUnit - https://junit.org/junit4/
junit = { module = "junit:junit", version.ref = "junit" }
Expand All @@ -90,27 +93,27 @@ junit = { module = "junit:junit", version.ref = "junit" }
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test" }

# Coroutines - https://github.com/Kotlin/kotlinx.coroutines
coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }

[plugins]
# Android Gradle Plugin - https://developer.android.com/studio/releases/gradle-plugin
android-application = { id = "com.android.application", version.ref = "androidGradlePlugin" }
android-library = { id = "com.android.library", version.ref = "androidGradlePlugin" }

# Kotlin Gradle Plugin - https://kotlinlang.org/docs/releases.html
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin"}
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin"}
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin"}
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin"}
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlin-kapt = { id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" }

# SQLDelight - https://cashapp.github.io/sqldelight/multiplatform_sqlite/
sqlDelight = { id = "app.cash.sqldelight", version.ref = "sqlDelight"}
sqlDelight = { id = "app.cash.sqldelight", version.ref = "sqlDelight" }

# Spotless - https://github.com/diffplug/spotless
spotless = { id = "com.diffplug.spotless", version.ref = "spotlessGradlePlugin"}
spotless = { id = "com.diffplug.spotless", version.ref = "spotlessGradlePlugin" }

# Detekt - https://detekt.dev/
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektGradlePlugin"}
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detektGradlePlugin" }

[bundles]
androidx-compose = [
Expand Down
1 change: 1 addition & 0 deletions infra/preferences/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ kotlin {

commonMain.dependencies {
implementation(libs.datastore)
implementation(libs.kotlinx.coroutines)
}

}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Felipe Joglar
* Copyright 2024 Felipe Joglar
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,6 @@
package com.taskodoro.storage.preferences

interface Preferences {
fun getBoolean(key: String): Boolean
fun setBoolean(key: String, value: Boolean)
suspend fun getBoolean(key: String): Boolean
suspend fun setBoolean(key: String, value: Boolean)
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Felipe Joglar
* Copyright 2024 Felipe Joglar
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -20,20 +20,26 @@ import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import com.taskodoro.storage.preferences.Preferences
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext

internal class DataStorePreferences(
private val dataStore: DataStore<androidx.datastore.preferences.core.Preferences>,
) : Preferences {

override fun getBoolean(key: String): Boolean = runBlocking {
return@runBlocking dataStore.data.first()[booleanPreferencesKey(key)] ?: false
override suspend fun getBoolean(key: String): Boolean {
return withContext(Dispatchers.IO) {
dataStore.data.first()[booleanPreferencesKey(key)] ?: false
}
}

override fun setBoolean(key: String, value: Boolean): Unit = runBlocking {
dataStore.edit { preferences ->
preferences[booleanPreferencesKey(key)] = value
override suspend fun setBoolean(key: String, value: Boolean) {
withContext(Dispatchers.IO) {
dataStore.edit { preferences ->
preferences[booleanPreferencesKey(key)] = value
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Felipe Joglar
* Copyright 2024 Felipe Joglar
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -38,11 +38,11 @@ class TestPreferences(
}
}

override fun getBoolean(key: String): Boolean {
override suspend fun getBoolean(key: String): Boolean {
return dataStorePreferences.getBoolean(key)
}

override fun setBoolean(key: String, value: Boolean) {
override suspend fun setBoolean(key: String, value: Boolean) {
dataStorePreferences.setBoolean(key, value)
}

Expand Down
2 changes: 1 addition & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ dependencyResolutionManagement {

enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")

rootProject.name = "Taskodoro_App"
rootProject.name = "taskodoro-apps"

include(":apps:android:app")
include(":taskodoro")
Expand Down
2 changes: 2 additions & 0 deletions taskodoro/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,12 @@ kotlin {
implementation(projects.infra.database)
implementation(projects.infra.preferences)
implementation(libs.kotlinx.datetime)
implementation(libs.kotlinx.coroutines)
}

commonTest.dependencies {
implementation(libs.kotlin.test)
implementation(libs.kotlinx.coroutines.test)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ internal class PreferencesOnboardingStore(
private const val IS_ONBOARDED_KEY = "is_onboarded_key"
}

override fun isOnboarded(): Result<Boolean> {
override suspend fun isOnboarded(): Result<Boolean> {
return runCatching {
preferences.getBoolean(IS_ONBOARDED_KEY)
}
}

override fun setOnboarded(): Result<Unit> {
override suspend fun setOnboarded(): Result<Unit> {
return runCatching {
preferences.setBoolean(IS_ONBOARDED_KEY, true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@
package com.taskodoro.onboarding.feature

interface OnboardingStore {
fun isOnboarded(): Result<Boolean>
fun setOnboarded(): Result<Unit>
suspend fun isOnboarded(): Result<Boolean>
suspend fun setOnboarded(): Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class TaskRepository(

object SaveFailed : Exception()

override fun save(task: Task): Result<Unit> =
override suspend fun save(task: Task): Result<Unit> =
try {
store.save(task)
Result.success(Unit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ package com.taskodoro.tasks.data
import com.taskodoro.tasks.feature.model.Task

interface TaskStore {
fun save(task: Task)
suspend fun save(task: Task)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,23 +19,28 @@ package com.taskodoro.tasks.data.local
import com.taskodoro.storage.db.TaskodoroDB
import com.taskodoro.tasks.data.TaskStore
import com.taskodoro.tasks.feature.model.Task
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.withContext

internal class SQLDelightTaskStore(
database: TaskodoroDB,
) : TaskStore {

internal val tasksQueries = database.localTaskQueries

override fun save(task: Task) {
tasksQueries.insert(
id = task.id.uuidString,
title = task.title,
description = task.description,
priority = task.priority.ordinal.toLong(),
completed = false,
dueDate = task.dueDate,
createdAt = task.createdAt,
updatedAt = 0,
)
override suspend fun save(task: Task) {
withContext(Dispatchers.IO) {
tasksQueries.insert(
id = task.id.uuidString,
title = task.title,
description = task.description,
priority = task.priority.ordinal.toLong(),
completed = false,
dueDate = task.dueDate,
createdAt = task.createdAt,
updatedAt = 0,
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ package com.taskodoro.tasks.feature
import com.taskodoro.tasks.feature.model.Task

interface TaskSaver {
fun save(task: Task): Result<Unit>
suspend fun save(task: Task): Result<Unit>
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import com.taskodoro.tasks.validator.TaskValidatorError
import com.taskodoro.tasks.validator.Validator

interface TaskNewUseCase {
operator fun invoke(
suspend operator fun invoke(
title: String,
description: String? = null,
dueDate: Long? = null,
Expand All @@ -35,7 +35,7 @@ class TaskNew(
private val now: () -> Long,
) : TaskNewUseCase {

override operator fun invoke(
override suspend operator fun invoke(
title: String,
description: String?,
dueDate: Long?,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.taskodoro.onboarding.data

import com.taskodoro.onboarding.feature.OnboardingStore
import com.taskodoro.storage.preferences.test.TestPreferences
import kotlinx.coroutines.test.runTest
import kotlin.test.AfterTest
import kotlin.test.Test
import kotlin.test.assertFalse
Expand All @@ -26,14 +27,14 @@ import kotlin.test.assertTrue
class OnboardingStoreTest {

@Test
fun isOnboarded_returnsFalseWhenNotPreviouslySet() {
fun isOnboarded_returnsFalseWhenNotPreviouslySet() = runTest {
val sut = makeSut()

assertFalse(sut.isOnboarded().getOrThrow())
}

@Test
fun setOnboarded_setsValueCorrectly() {
fun setOnboarded_setsValueCorrectly() = runTest {
val sut = makeSut()

sut.setOnboarded()
Expand Down
Loading
Loading