Skip to content

Instantly share code, notes, and snippets.

View odbol's full-sized avatar

Tyler Freeman odbol

View GitHub Profile
@odbol
odbol / gist:20de75aff4d0175c79cc5d0e5dda0ed1
Created February 17, 2025 02:33
Utils for use coroutines from Java code, like calling Flow.collect() from Java
package com.odbol.coroutines
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.coroutineScope
import java.util.function.Consumer
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
/** Helps using Kotlin coroutines from Java code */
object CoroutineHelper {
@odbol
odbol / StringEnumTypeAdapter.java
Created February 6, 2025 01:06
GSON adapter for string enums when you want the JSON to have the string value instead of the enum constant's name
/*
* Copyright (C) 2024 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
@odbol
odbol / example.tsv
Last active May 2, 2024 22:21
AppScript to fix Google Sheets with =IMAGE() formulas that contain data-urls
We can make this file beautiful and searchable if this error is corrected: Illegal quoting in line 2.
Image key Image Another column
1 =IMAGE("data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7") Random data
2 =IMAGE("data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7") More Random data
@odbol
odbol / Regexes.md
Created February 5, 2024 18:11
Useful Regexes

Find all <style> tags and their contents:

``

@odbol
odbol / woocommerce-bulk-update-prices.md
Last active January 15, 2024 22:25
WooCommerce: how to update prices in bulk directly in the database using SQL

WooCommerce: how to update prices in bulk without a plugin

The WooCommerce Wordpress plugin doesn't have a way to update all prices for all products and all variations in bulk. You have to do it by hand, in the Wordpress admin editor, or pay for a "bulk edit" plugin to do it.

Or, you can hack the database directly using some fancy SQL. It took me a while to figure this out.

-- Update all prices for all variations and products that are 4.99, change to 5.99
@odbol
odbol / FractionsSequence.kt
Created December 5, 2022 18:15
Kotlin sequence generator for stepping through float ranges without accumulating floating-point errors
fun generateSequenceOfFractions(
range: ClosedFloatingPointRange<Float>,
step: Float
): Sequence<Float> {
val multiplier = 1f / step
val start = floor(range.start * multiplier).toInt()
val endInclusive = ceil(range.endInclusive * multiplier).toInt()
return generateSequence(start) { it + 1 }
.takeWhile { it <= endInclusive }
.map{ it.toFloat() / multiplier }
@odbol
odbol / Utils.ts
Created October 3, 2022 22:45
Utility functions for parsing querystrings and other useful JS goodies
/** Returns the first querystring parameter with the given key, or null if not found. */
export function getParam(param: string): string|null {
var dataCallbackMatches = new RegExp(param + '=([^&]+)').exec(document.location.href);
if (dataCallbackMatches) {
return dataCallbackMatches[1];
} else {
return null;
}
};
@odbol
odbol / PendingRequest.ts
Created August 4, 2022 23:11
PendingRequest: a way to implement Promise-based APIs across process boundaries like iframes or ServiceWorkers.
import {Deferred} from './Deferred.js'; // See https://gist.github.com/odbol/1a98cf6186caaace78cae9e7a249c992
/**
* A PendingRequest.
*/
export interface PendingRequest<T> {
/**
* Id of the request for resolving/rejecting later.
*/
requestId: number;
@odbol
odbol / Deferred.ts
Created August 4, 2022 23:06
Deferred: a Promise that you can resolve or reject after the fact.
/**
* A Promise that you can resolve or reject after the fact.
*/
export class Deferred<T> {
private _resolve?: (result: T) => void;
private _reject?: (error: Error) => void;
promise: Promise<T>;
constructor() {
this.promise = new Promise((resolve, reject) => {
@odbol
odbol / AnimationUtils.ts
Created July 15, 2022 22:19
Collection of mathy math functions for mathing and animating
export type float = number;
/**
* Interpolate a value with specified extrema, to a new value between new extrema.
*
* @param value the current value
* @param inputMin minimum the input value can reach
* @param inputMax maximum the input value can reach
* @param outputMin minimum the output value can reach
* @param outputMax maximum the output value can reach