Skip to content

Instantly share code, notes, and snippets.

@edenman
edenman / SpoonScreenshotAction.java
Last active May 17, 2017 16:12
Espresso ViewAction for Spoon Screenshot
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 / CALayerExtension.swift
Last active October 6, 2016 02:24
Swift (2.3) CALayer extension to only round _some_ corners
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 February 24, 2017 01:56
Kotlin lazy delegate that enforces single-initialization by ensuring callers are on the main thread
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 / Extension.kt
Created November 15, 2017 22:19
View.observeVisibility()
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 November 20, 2017 23:44
A helper class that exposes observables for two different types, as well as a single observable for both
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 February 16, 2019 01:05
Original code by @JakeWharton, ported to Kotlin. Useful if you want to maintain insertion order of a Map before/after Moshi serialization.
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]
(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
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,
@edenman
edenman / gist:e00f89c8493b8a2c591dff6302f80fe7
Created February 18, 2021 18:59
kotlinx serialization compile error for kotlin/native
> Task :shareddata:linkReleaseFrameworkIos FAILED
e: Compilation failed: null
* Source files:
* Compiler version info: Konan: 1.4.30-M1 / Kotlin: 1.4.30
* Output kind: FRAMEWORK
e: java.lang.NullPointerException
at org.jetbrains.kotlin.backend.konan.optimizations.ModuleDFGBuilder$FunctionDFGBuilder.getNode(DFGBuilder.kt:614)
at org.jetbrains.kotlin.backend.konan.optimizations.ModuleDFGBuilder$FunctionDFGBuilder.expressionToScopedEdge(DFGBuilder.kt:591)
@edenman
edenman / download-files-from-export.py
Created December 9, 2021 01:22
Script for downloading all files from a Quill team export
# Run this script to download all of the files that were uploaded to public channels in your Team.
# Usage: cd my-files-dir && python download-files-from-export.py -f /Users/myusername/Downloads/export-filename.zip
import zipfile
import getopt
import sys
import re
import json
import os.path
import os