This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal sealed interface ScreenUiState { | |
data object Loading : ScreenUiState | |
data object Success : ScreenUiState | |
data object Empty : ScreenUiState | |
data class Error(val error: Throwable) : ScreenUiState | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
companion object { | |
private const val PREF_NAME = "example_pref" | |
private val EXAMPLE_DATA1 = stringPreferencesKey("exampleData1") | |
private val EXAMPLE_DATA2 = booleanPreferencesKey("exampleData2") | |
private val EXAMPLE_DATA3 = intPreferencesKey("exampleData3") | |
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore( | |
name = PREF_NAME, | |
produceMigrations = { context -> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class ExampleDataStore(context: Context) { | |
private val dataStore: DataStore<Preferences> = context.dataStore | |
suspend fun setExampleData(exampleData: String?) { | |
dataStore.storeValue(EXAMPLE_DATA, exampleData) | |
} | |
suspend fun getExampleData(): String? { | |
return dataStore.readValue(EXAMPLE_DATA) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend inline fun <T : Any> DataStore<Preferences>.storeValue(key: Preferences.Key<T>, value: T?) { | |
edit { preferences -> | |
if (value == null) { | |
preferences.remove(key) | |
} else { | |
preferences[key] = value | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
suspend inline fun <T : Any> DataStore<Preferences>.readValue(key: Preferences.Key<T>, defaultValue: T): T { | |
return data.catch { recoverOrThrow(it) }.map { it[key] }.firstOrNull() ?: defaultValue | |
} | |
suspend inline fun <T : Any> DataStore<Preferences>.readValue(key: Preferences.Key<T>): T? { | |
return data.catch { recoverOrThrow(it) }.map { it[key] }.firstOrNull() | |
} | |
suspend fun FlowCollector<Preferences>.recoverOrThrow(throwable: Throwable) { | |
if (throwable is IOException) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public suspend fun DataStore<Preferences>.edit( | |
transform: suspend (MutablePreferences) -> Unit | |
): Preferences { | |
return this.updateData { | |
// It's safe to return MutablePreferences since we freeze it in | |
// PreferencesDataStore.updateData() | |
it.toMutablePreferences().apply { transform(this) } | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
val EXAMPLE_COUNTER = intPreferencesKey("example_counter") | |
val exampleCounterFlow: Flow<Int> = context.dataStore.data | |
.map { preferences -> | |
// No type safety. | |
preferences[EXAMPLE_COUNTER] ?: 0 | |
} | |
suspend fun incrementCounter() { | |
context.dataStore.edit { settings -> | |
val currentCounterValue = settings[EXAMPLE_COUNTER] ?: 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
single.retryWhen { attempts -> | |
Flowables.zip( | |
attempts.map { error -> if (predicates.count { it(error) } > 0) error else throw error }, | |
Flowable.interval(interval, unit) | |
).map { (error, retryCount) -> if (retryCount >= maxRetries) throw error } | |
} | |
single.onErrorResumeNext(resumeNext) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
internal class ImagesRepositoryImpl(private val source: ImageDataSource) : ImagesRepository { | |
override fun getImages(params: Map<String, String>): Single<Result<ImagesResponse>> { | |
return source.getImages(params) | |
.map { Result.success(it) } | |
.onErrorResumeNext { Single.just(Result.failure(it)) } | |
.compose(applyRetryPolicy(TIMEOUT) { Single.just(Result.failure(it)) }) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
this += repository.getImages(params) | |
.compose(applySingleAsync()) | |
.subscribe { result -> | |
result.fold( | |
onSuccess = { }, | |
onFailure = { } | |
) | |
} |
NewerOlder