Skip to content

Instantly share code, notes, and snippets.

View afollestad's full-sized avatar
📱

Aidan Follestad afollestad

📱
View GitHub Profile
@afollestad
afollestad / .zshrc
Last active September 18, 2022 01:26
export JAVA_HOME='/Users/afollestad/Library/Java/JavaVirtualMachines/azul-11-ARM64'
export ANDROID_SDK_ROOT=$HOME/Library/Android/sdk
export PATH="$HOME/Library/Android/sdk/tools:$HOME/Library/Android/sdk/platform-tools:$PATH"
alias gw="./gradlew "
alias dev="cd ~/Development"
alias gcm="git commit -am "
alias gco="git checkout "
alias gpu="git push "
alias gpl="git pull "
@file:Suppress("unused", "MemberVisibilityCanBePrivate")
package com.afollestad.flow.util
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers.Unconfined
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
@FlowPreview
@ExperimentalCoroutinesApi
fun main() {
runBlocking {
class CommandLineParser(
private val input: String
) : Iterator<String> {
private var lastIndex: Int = 0
override fun hasNext(): Boolean = lastIndex in 0..input.length - 2
override fun next(): String {
val value = StringBuilder()
var quoteStarter: Char? = null
import android.graphics.Typeface
import androidx.annotation.CheckResult
import java.lang.Exception
/** @author Aidan Follestad (@afollestad) */
object TypefaceHelper {
private val cache = hashMapOf<String, Typeface>()
/**
* Gets a typeface by its family name. Automatically statically caches it to avoid
@afollestad
afollestad / Debouncer.kt
Created June 12, 2019 18:08
Debounce clicks in Kotlin
import android.view.View
internal object Debouncer {
@Volatile private var enabled: Boolean = true
private val enableAgain = Runnable { enabled = true }
fun canPerform(view: View): Boolean {
if (enabled) {
enabled = false
view.post(enableAgain)
@afollestad
afollestad / gist:e1ada7b0c1d3a390e4b97910846cba69
Created April 19, 2019 00:10
List of components that can be installed on Travis.ci
addon-google_apis-google-10
addon-google_apis-google-11
addon-google_apis-google-12
addon-google_apis-google-13
addon-google_apis-google-14
addon-google_apis-google-15
addon-google_apis-google-16
addon-google_apis-google-17
addon-google_apis-google-18
addon-google_apis-google-19
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
fun EditText.onTextChanged(
@IntRange(from = 0, to = 10000) debounce: Int = 0,
cb: (String) -> Unit
) {
addTextChangedListener(object : TextWatcher {
val callbackRunner = Runnable {
@afollestad
afollestad / LifecycleAwareDisposable.kt
Created December 14, 2018 19:09
Make an Observable Lifecycle aware - disposing itself when the lifecycle stops
/** @author Aidan Follestad (afollestad) */
class LifecycleAwareDisposable(
private val disposable: Disposable
) : LifecycleObserver {
@OnLifecycleEvent(ON_DESTROY)
fun dispose() = disposable.dispose()
}
/** @author Aidan Follestad (afollestad) */
@afollestad
afollestad / LivedataMap.kt
Created December 14, 2018 18:55
Map and switchMap live data with extension functions instead of method calls.
import androidx.lifecycle.LiveData
import androidx.lifecycle.Transformations
fun <X, Y> LiveData<X>.map(mapper: (X) -> Y) =
Transformations.map(this, mapper)!!
fun <X, Y> LiveData<X>.switchMap(mapper: (X) -> LiveData<Y>) =
Transformations.switchMap(this, mapper)!!