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

Switch to compose state and kotlin flows - 1. iteration #279

Merged
merged 13 commits into from
Apr 15, 2024
40 changes: 40 additions & 0 deletions app/src/androidTest/java/at/bitfire/icsdroid/TestSettings.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package at.bitfire.icsdroid

import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withTimeout
import org.junit.Test

class TestSettings {
companion object {
val appContext: Context by lazy { InstrumentationRegistry.getInstrumentation().targetContext }
}

@Test
fun testForceDarkModeFlow() {
// Initialize settings
val settings = Settings(appContext)
// Create a variable for storing the value of the preference when updated
var forceDarkMode = false
// Launch a coroutine to collect the flow
CoroutineScope(Dispatchers.IO).launch {
settings.forceDarkModeFlow().collect { forceDarkMode = it }
}
// Set the preference to true
settings.forceDarkMode(true)
// Wait for the flow to update, or throw timeout
runBlocking {
withTimeout(1000) {
while (!forceDarkMode) {
delay(10)
}
}
}
assert(forceDarkMode)
}
}
24 changes: 24 additions & 0 deletions app/src/main/java/at/bitfire/icsdroid/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ package at.bitfire.icsdroid
import android.content.Context
import android.content.SharedPreferences
import androidx.lifecycle.LiveData
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow

class Settings(context: Context) {

Expand All @@ -19,6 +22,10 @@ class Settings(context: Context) {

fun forceDarkMode(): Boolean = prefs.getBoolean(FORCE_DARK_MODE, false)

@Deprecated(
message = "Replace LiveData by Flows",
replaceWith = ReplaceWith("forceDarkModeFlow()")
)
fun forceDarkModeLive(): LiveData<Boolean> = object: LiveData<Boolean>() {
val listener = SharedPreferences.OnSharedPreferenceChangeListener { prefs, key ->
if (key == FORCE_DARK_MODE) {
Expand All @@ -37,6 +44,23 @@ class Settings(context: Context) {
}
}

fun forceDarkModeFlow(): Flow<Boolean> = callbackFlow {
val listener = SharedPreferences.OnSharedPreferenceChangeListener { prefs, key ->
if (key == FORCE_DARK_MODE) {
val forceDarkMode = prefs.getBoolean(key, false)
trySend(forceDarkMode)
}
}

prefs.registerOnSharedPreferenceChangeListener(listener)
listener.onSharedPreferenceChanged(prefs, FORCE_DARK_MODE)

awaitClose {
// Remove listener
prefs.unregisterOnSharedPreferenceChangeListener(listener)
}
}

fun forceDarkMode(force: Boolean) {
// save setting
prefs.edit()
Expand Down
16 changes: 15 additions & 1 deletion app/src/main/java/at/bitfire/icsdroid/SyncWorker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import android.content.ContentProviderClient
import android.content.ContentUris
import android.content.Context
import android.util.Log
import androidx.work.*
import androidx.work.Constraints
import androidx.work.CoroutineWorker
import androidx.work.ExistingWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import at.bitfire.ical4android.AndroidCalendar
import at.bitfire.ical4android.util.MiscUtils.closeCompat
import at.bitfire.icsdroid.Constants.TAG
Expand Down Expand Up @@ -79,9 +86,16 @@ class SyncWorker(
.enqueue()
}

@Deprecated(
message = "Replace LiveData by Flows",
replaceWith = ReplaceWith("statusFlow(context)")
)
fun liveStatus(context: Context) =
WorkManager.getInstance(context).getWorkInfosForUniqueWorkLiveData(NAME)

fun statusFlow(context: Context) =
WorkManager.getInstance(context).getWorkInfosForUniqueWorkFlow(NAME)

}

private val database = AppDatabase.getInstance(applicationContext)
Expand Down
22 changes: 22 additions & 0 deletions app/src/main/java/at/bitfire/icsdroid/db/dao/SubscriptionsDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.room.Relation
import androidx.room.Update
import at.bitfire.icsdroid.db.entity.Credential
import at.bitfire.icsdroid.db.entity.Subscription
import kotlinx.coroutines.flow.Flow

@Dao
interface SubscriptionsDao {
Expand All @@ -21,9 +22,16 @@ interface SubscriptionsDao {
@Delete
fun delete(vararg subscriptions: Subscription)

@Deprecated(
message = "Replace LiveData by Flows",
replaceWith = ReplaceWith("getAllFlow()")
)
@Query("SELECT * FROM subscriptions")
fun getAllLive(): LiveData<List<Subscription>>

@Query("SELECT * FROM subscriptions")
fun getAllFlow(): Flow<List<Subscription>>

@Query("SELECT * FROM subscriptions")
fun getAll(): List<Subscription>

Expand All @@ -36,12 +44,26 @@ interface SubscriptionsDao {
@Query("SELECT * FROM subscriptions WHERE url=:url")
fun getByUrl(url: String): Subscription?

@Deprecated(
message = "Replace LiveData by Flows",
replaceWith = ReplaceWith("getWithCredentialsByIdFlow(id)")
)
@Query("SELECT * FROM subscriptions WHERE id=:id")
fun getWithCredentialsByIdLive(id: Long): LiveData<SubscriptionWithCredential>

@Query("SELECT * FROM subscriptions WHERE id=:id")
fun getWithCredentialsByIdFlow(id: Long): Flow<SubscriptionWithCredential>

@Deprecated(
message = "Replace LiveData by Flows",
replaceWith = ReplaceWith("getErrorMessageFlow(id)")
)
@Query("SELECT errorMessage FROM subscriptions WHERE id=:id")
fun getErrorMessageLive(id: Long): LiveData<String?>

@Query("SELECT errorMessage FROM subscriptions WHERE id=:id")
fun getErrorMessageFlow(id: Long): Flow<String?>

@Update
fun update(subscription: Subscription)

Expand Down
Loading