Skip to content

Instantly share code, notes, and snippets.

Avatar

Eric Denman edenman

View GitHub Profile
@edenman
edenman / CALayerExtension.swift
Last active Oct 6, 2016
Swift (2.3) CALayer extension to only round _some_ corners
View CALayerExtension.swift
extension CALayer {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let maskPath = UIBezierPath(roundedRect: bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let shape = CAShapeLayer()
shape.path = maskPath.CGPath
mask = shape
}
@edenman
edenman / LazyMainThread.kt
Created Feb 24, 2017
Kotlin lazy delegate that enforces single-initialization by ensuring callers are on the main thread
View LazyMainThread.kt
package my.package.foo
/**
* This method is just a modification of the kotlin stdlib lazy initializer, which by default uses a
* synchronized block to ensure no double-running of the initializer. Synchronized blocks are not
* particularly fast on Android so we try to avoid them when possible: in all of our cases, the
* lazy property is being accessed on the main thread, so it's easier to just check that we're on
* the main thread as a way to ensure no double-running of the initializer.
*/
fun <T> lazyMainThread(initializer: () -> T): Lazy<T> = LazyMainThreadImpl(initializer)
@edenman
edenman / SpoonScreenshotAction.java
Last active May 17, 2017
Espresso ViewAction for Spoon Screenshot
View SpoonScreenshotAction.java
import android.app.Activity;
import android.content.Context;
import android.content.ContextWrapper;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.view.View;
import com.squareup.spoon.Spoon;
import org.hamcrest.Matcher;
import org.hamcrest.Matchers;
@edenman
edenman / Extension.kt
Created Nov 15, 2017
View.observeVisibility()
View Extension.kt
fun View.observeVisibility(): Observable<Int> =
Observable.create(ViewVisibilityChangeOnSubscribe(this), BackpressureMode.LATEST)
private class ViewVisibilityChangeOnSubscribe(private val view: View) : Action1<Emitter<Int>> {
override fun call(emitter: Emitter<Int>) {
val listener = OnGlobalLayoutListener {
if (view.viewTreeObserver.isAlive) {
emitter.onNext(view.visibility)
}
}
@edenman
edenman / RelayPair.kt
Created Nov 20, 2017
A helper class that exposes observables for two different types, as well as a single observable for both
View RelayPair.kt
class RelayPair<A, B> {
private val relayA = BehaviorRelay.create(null as A?)
private val relayB = BehaviorRelay.create(null as B?)
private val relayBoth = BehaviorRelay.create(Both<A, B>(null, null))
data class Both<out A, out B>(val a: A?, val b: B?)
fun publishA(value: A?) {
relayA.call(value)
relayBoth.call(relayBoth.value.copy(a = value))
@edenman
edenman / LinkedHashMapAdapterFactory.kt
Last active Feb 16, 2019
Original code by @JakeWharton, ported to Kotlin. Useful if you want to maintain insertion order of a Map before/after Moshi serialization.
View LinkedHashMapAdapterFactory.kt
class LinkedHashMapAdapterFactory : Factory {
override fun create(type: Type, annotations: MutableSet<out Annotation>,
moshi: Moshi): JsonAdapter<*>? {
if (Types.getRawType(type) != LinkedHashMap::class.java) {
return null
}
if (type !is ParameterizedType) {
throw IllegalStateException("Non-parameterized LinkedHashMap is not supported")
}
val keyType = type.actualTypeArguments[0]
View gist:9a865c210c19cb11519261ddf3d93abf
(00:10:54) ERROR: /root/recharge/src/server/store/BUILD:109:1: GoLink src/server/store/linux_amd64_stripped/go_default_test failed (Exit 1)
panic: found import cycle while visiting server/store
goroutine 1 [running]:
cmd/link/internal/ld.dfs(0xc420596780, 0xc420492dd0, 0xc420492db8)
/usr/local/go/src/cmd/link/internal/ld/lib.go:2280 +0x286
cmd/link/internal/ld.dfs(0xc427186240, 0xc420492dd0, 0xc420492db8)
/usr/local/go/src/cmd/link/internal/ld/lib.go:2284 +0x10e
cmd/link/internal/ld.dfs(0xc422a3f680, 0xc420492dd0, 0xc420492db8)
/usr/local/go/src/cmd/link/internal/ld/lib.go:2284 +0x10e
View NotificationToBuilder.kt
private fun Notification.toBuilder(): NotificationCompat.Builder {
val builder = NotificationCompat.Builder(app, CHANNEL_ID)
.setSmallIcon(smallIcon.resId)
.setAutoCancel(flags and Notification.FLAG_AUTO_CANCEL == Notification.FLAG_AUTO_CANCEL)
.setCategory(category)
.setStyle(messagingStyle())
.setContentIntent(contentIntent)
actions.forEach { action ->
val actionBuilder = NotificationCompat.Action.Builder(
action.icon,
You can’t perform that action at this time.