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
this += repository.getImages(params) | |
.compose(applySingleAsync()) | |
.subscribe { result -> | |
result.fold( | |
onSuccess = { }, | |
onFailure = { } | |
) | |
} |
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) } | |
.compose(applyRetryPolicy(TIMEOUT, maxRetries = 5, interval = 2, unit = TimeUnit.SECONDS) { 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
internal typealias RETRY_PREDICATE = (Throwable) -> Boolean | |
internal const val MAX_RETRIES = 3L | |
internal const val DEFAULT_INTERVAL = 1L | |
internal val TIMEOUT: RETRY_PREDICATE = { it is SocketTimeoutException } | |
internal val NETWORK: RETRY_PREDICATE = { it is IOException } | |
internal val SERVICE_UNAVAILABLE: RETRY_PREDICATE = { it is HttpException && it.code() == 503 } | |
internal fun <T> applyRetryPolicy( |
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 |
NewerOlder