Skip to content

Instantly share code, notes, and snippets.

View timusus's full-sized avatar

Tim Malseed timusus

  • Itty Bitty Apps
  • Melbourne, Victoria
View GitHub Profile
@timusus
timusus / ElapsedTimeIdlingResource.kt
Created November 30, 2021 00:36
Compose Elapsed Time Idling Resource
import androidx.compose.ui.test.IdlingResource
/**
* An [IdlingResource] which reports itself as idle until [waitingTime] has elapsed.
*/
class ElapsedTimeIdlingResource(private val waitingTime: Long) : IdlingResource {
var startTime: Long = System.currentTimeMillis()
override val isIdleNow: Boolean
@timusus
timusus / HomeContract.kt
Last active April 21, 2020 10:53
Shuttle - Home Contract
// This Gist demonstrates the use of MVP in an Android project.
// File 1 - The contract. Defines the View and Presenter interface.
// File 2 - The Presenter implementation
// File 3 - The View implementation (ViewController / Fragment)
// I like this architecture because it helps with separation of concerns. The business logic is carried out
// in the Presenter, which has no (or limited) knowledge of Android framework components (which also makes it easier to test)
// The View Controller (Fragment) is then kept very lightweight, and only deals with updating views and dispatching
@timusus
timusus / EqualizerAudioProcessor.kt
Last active November 16, 2019 01:47
EqualizerAudioProcessor
class EqualizerAudioProcessor : BaseAudioProcessor() {
lateinit var prevXArray: Array<ShortArray>
lateinit var prevYArray: Array<ShortArray>
override fun configure(sampleRateHz: Int, channelCount: Int, encoding: Int): Boolean {
val flush = setInputFormat(sampleRateHz, channelCount, encoding)
prevXArray = Array(channelCount) { ShortArray(2) { 0 } }
prevYArray = Array(channelCount) { ShortArray(2) { 0 } }
/**
* Executes a unit of work at a specified interval.
*
* An attempt threshold can be specified. If the number of attempts to execute the work exceeds this threshold, `didExceedAttemptThreshold()` is called and the timer is
* invalidated.
*
* An error threshold can also be specified. If the number of errors exceeds this threshold, `didExceedErrorThreshold()` is called, and the latest error is passed in.
*
* Note: This class uses a Timer to execute the work, ensure to call `stop()` when no longer interested in the result, or a leak may occur.
*
call.enqueue {
override fun onResult(result: Result) {
when(result){
is Success -> {
// Handle Success
}
is Failure -> {
presentAlert(
title = "Login Failed",
message = result.error.userDescription()
val responseErrorMapper: (retrofit2.Response<*>) -> Error? = { response ->
// Todo: Map response into your custom error type
}
@timusus
timusus / Retrofit.kt
Created October 20, 2018 03:31
Retrofit CallAdapter
val retrofit = Retrofit.Builder()
.addCallAdapterFactory(CallResultAdapterFactory(responseErrorMapper))
.baseUrl(baseUrl)
.client(okHttpClient)
.addConverterFactory(converterFactory)
.build()
val responseErrorMapper: (Response<*>) -> Error? = { response ->
response.errorBody()?.string()?.let { errorBody ->
// Is this an OAuthError?
OAuthError.errorData(response, errorBody)?.let { errorData ->
OAuthError(response, errorData)
}
}
}
@timusus
timusus / Enqueue.kt
Created October 20, 2018 03:29
Sealed result Retrofit enqueue snippet
call.enqueue {
override fun onResult(result: Result) {
when(result){
is Success -> {
// Handle Success
}
is Failure -> {
// Handle failure
result.error.doSomething()
}
@timusus
timusus / Result.kt
Created October 20, 2018 03:27
Sealed Class Snippet
sealed class Result<out T> {
data class Success<out T>(val data: T?) : Result<T>()
data class Failure(val error: Error) : Result<Nothing>()
}