Skip to content

Instantly share code, notes, and snippets.

View nwellis's full-sized avatar

nwellis nwellis

  • Minneapolis, MN
View GitHub Profile
@nwellis
nwellis / AuthHeaderInterceptor.kt
Last active October 12, 2022 23:39
OkHttp auth header interceptor with retry logic
import androidx.annotation.WorkerThread
import kotlinx.coroutines.runBlocking
import okhttp3.Interceptor
import okhttp3.Request
import okhttp3.Response
import timber.log.Timber
object Retried
/**
@nwellis
nwellis / Hexagons.js
Created February 15, 2021 14:19
Uses and SVG and MUI styles to create a hexagon background
import React from "react";
import { makeStyles } from "@material-ui/core/styles";
const hexagonColor = (_theme) => "#000";
const strokeColor = (theme) => theme.palette.background.default;
const useStyles = makeStyles((theme) => ({
root: {
"& svg": {
background: hexagonColor(theme),
@nwellis
nwellis / RetrofitMockKs.kt
Created December 9, 2020 17:26
Retrofit network call behavior mocked with MockK
fun newMockHttpException(
statusCode: Int = 400,
message: String = "Default mock error",
response: Response<Any>? = mockk<Response<Any>>(relaxed = true)
.applyMockDefaults<Any, Any>(statusCode = statusCode)
) = mockk<HttpException>().applyMockDefaults(statusCode, message, response)
fun HttpException.applyMockDefaults(
statusCode: Int = 400,
message: String = "Default mock error",
@nwellis
nwellis / TimeoutInterceptor.kt
Created December 8, 2020 20:51
Interceptor that allows override timeout settings per call.
const val CONNECT_TIMEOUT_MS = "CONNECT_TIMEOUT_MS"
const val READ_TIMEOUT_MS = "READ_TIMEOUT_MS"
const val WRITE_TIMEOUT_MS = "WRITE_TIMEOUT_MS"
/**
* Allows dynamic setting of timeout headers.
*
* Usage:
* ```
* @Headers("$CONNECT_TIMEOUT:10000", "$READ_TIMEOUT:10000", "$WRITE_TIMEOUT:10000")
@nwellis
nwellis / SemanticVersion.kt
Created December 7, 2020 15:40
Kotlin data class that parses a string into a semantic version, where each major/minor/patch is an integer.
data class SemanticVersion(val major: Int, val minor: Int, val patch: Int) {
companion object {
fun fromString(version: String?): SemanticVersion? = version
?.takeIf { it.isNotBlank() }
?.split(".")
?.let { split ->
return SemanticVersion(
major = split.getOrNull(0)?.toIntOrNull() ?: 0,
minor = split.getOrNull(1)?.toIntOrNull() ?: 0,
patch = split.getOrNull(2)?.toIntOrNull() ?: 0
import { useState, useMemo, useCallback, useEffect } from 'react';
const initialState = {
isLoading: false,
result: null,
error: null
};
/**
* This could probably be done in a much better way. Seems really messy
import { useMemo, useEffect, useState } from 'react';
import { useDebounce } from 'use-debounce';
export default function(debounceWaitMs = 500) {
const [curWindowHeightPx, setWindowHeight] = useState(window.innerHeight);
const [windowHeightPx] = useDebounce(curWindowHeightPx, debounceWaitMs, {
leading: true
});
useEffect(() => {
@nwellis
nwellis / Resource.kt
Last active December 8, 2020 20:54
Resource wrappers in Kotlin and Typescript
sealed class Resource<T> {
object Loading: Resource<Nothing>()
data class Success<T>(val data: T): Resource<T>()
data class Error(val error: AppError): Resource<Nothing>()
}
@nwellis
nwellis / SquareCutoutOverlay.kt
Created January 24, 2019 15:33
View to add a semitransparent overlay with a fully transparent square cutout
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.View
import kotlin.math.max
import kotlin.math.min
class SquareCutoutOverlay(
context: Context,
abstract class UiComponent(@LayoutRes val layoutId: Int,
val root: ViewGroup,
val activity: FragmentActivity)
{
val mainView: View = View.inflate(activity, layoutId, root)
lateinit protected var unbinder: Unbinder
open fun unbind() {