Skip to content

Instantly share code, notes, and snippets.

class StateHolder<T : Any>(state: T) {
private val _liveData = MutableLiveData(state)
val liveData: LiveData<T> get() = _liveData
private var _value: T = state
val value: T get() = _value
fun update(notify: Boolean = true, block: T.() -> T) {
synchronized(LOCK) {
_value = block(value)
@Keep
internal class LoggingHandler : AbstractCoroutineContextElement(CoroutineExceptionHandler),
CoroutineExceptionHandler {
override fun handleException(context: CoroutineContext, exception: Throwable) {
Crashlytics.logException(exception)
// Since we don't want to crash and Coroutines will call the current thread's handler, we
// install a noop handler and then reinstall the existing one once coroutines calls the new
// handler.
Thread.currentThread().apply {
public suspend inline fun <T : Closeable?, R> T.useCancellably(
crossinline block: (T) -> R
): R = suspendCancellableCoroutine { cont ->
cont.invokeOnCancellation { this?.close() }
cont.resume(use(block))
}
infix fun <T> Boolean.q(primary: T) = if (this) Ternary(primary) else null
infix fun <T> Ternary<T>?.e(other: T) = if (this == null) other else result
data class Ternary<T>(internal val result: T)
val bool = true
println(bool q "true" e "false")
@SUPERCILEX
SUPERCILEX / Async.kt
Created March 27, 2018 06:02
Google Play Services Tasks API with Kotlin Coroutines support
suspend fun <T> Task<T>.await(): T {
if (isComplete) return if (isSuccessful) result else throw exception!!
return suspendCoroutine { c: Continuation<T> ->
addOnSuccessListener { c.resume(it) }
addOnFailureListener { c.resumeWithException(it) }
}
}
fun <T> Deferred<T>.asTask(): Task<T> {
val source = TaskCompletionSource<T>()
@SUPERCILEX
SUPERCILEX / MovableFragmentStatePagerAdapter.kt
Last active April 5, 2019 16:25
A PagerAdapter that can withstand item reordering. See https://issuetracker.google.com/issues/36956111.
import android.annotation.SuppressLint
import android.os.Bundle
import android.os.Parcelable
import android.support.v4.app.Fragment
import android.support.v4.app.FragmentManager
import android.support.v4.app.FragmentTransaction
import android.view.View
import android.view.ViewGroup
import java.util.HashSet
import java.util.LinkedHashMap
service cloud.firestore {
match /databases/{database}/documents {
// Incorrect solution
match /public/{doc=**} {
allow read;
match /foo/{bar} {
allow write: if doc == "foobar"; // Error! "doc" is a path object, not a string
}
}
service cloud.firestore {
match /databases/{database}/documents {
// Incorrect solution
match /teams/{teamId} {
allow read: ...;
allow write: if request.resource.data.owners[request.auth.uid] is int // Returns false on delete!
&& isValidTeam();
}
// Correct solution
service cloud.firestore { // Boilerplate!
match /databases/{database}/documents { // More boilerplate.
match /{document=**} {
allow read, write;
}
}
}
// Creating tables for v1
db.execSQL("CREATE TABLE mutation_queues (uid TEXT PRIMARY KEY, last_acknowledged_batch_id INTEGER, last_stream_token BLOB)");
db.execSQL("CREATE TABLE mutations (uid TEXT, batch_id INTEGER, mutations BLOB, PRIMARY KEY (uid, batch_id))");
db.execSQL("CREATE TABLE document_mutations (uid TEXT, path TEXT, batch_id INTEGER, PRIMARY KEY (uid, path, batch_id))");
db.execSQL("CREATE TABLE targets (target_id INTEGER PRIMARY KEY, canonical_id TEXT, snapshot_version_seconds INTEGER, snapshot_version_nanos INTEGER, resume_token BLOB, last_listen_sequence_number INTEGER,target_proto BLOB)");
db.execSQL("CREATE INDEX query_targets ON targets (canonical_id, target_id)");
db.execSQL("CREATE TABLE target_globals (highest_target_id INTEGER, highest_listen_sequence_number INTEGER)");
db.execSQL("CREATE TABLE target_documents (target_id INTEGER, path TEXT, PRIMARY KEY (target_id, path))");
db.execSQL("CREATE INDEX document_targets ON target_documents (path, target_id)");
db.execSQL("CREATE TABLE remot