Skip to content

Instantly share code, notes, and snippets.

View srph's full-sized avatar
🛠️
Building @Stride-Labs Frontend

Kier Borromeo srph

🛠️
Building @Stride-Labs Frontend
View GitHub Profile
@srph
srph / chunk-pattern.ts
Created March 20, 2023 11:13
JS: Slice an array based on provided pattern
// @source https://github.com/srph/chunk-pattern/blob/master/index.js
// Slices the array into chunks based on the pattern.
// Useful for intentionally splitting an array into rows and columns on a specific pattern.
// e.g., display 4 on top, 2 on bottom.
// @use chunkPattern([1, 2, 3, 4, 5], [2, 3]) => [[1, 2], [3, 4, 5]]
// @use chunkPattern([1, 2, 3, 4, 5], [4, 1]) => [[1, 2, 3, 4], [5]]
const chunkPattern = <T>(array: readonly T[], pattern: number[]): Array<T[]> => {
const result: Array<T[]> = [[]]
let patternIndex: number = 0
let patternCount: number = pattern[0]
@srph
srph / gist:1cce7fcf97c83bff86b7a36364739c5c
Created February 19, 2023 02:12
data structure for drag and drop feature with react-query
// API
{
items: []
}
// Query
{
items: {
[id]: {
id: 1,
@srph
srph / poll.ts
Created January 11, 2023 13:02
JS: Poll until condition is true (with max attempts and manual abort)
@@ -0,0 +1,44 @@
import { delay } from '../time'
type PollValueCallback<T> = () => Promise<T>
type PollConditionCallback<T> = (t: T) => boolean
interface PollOptions {
ms?: number
max?: number
@srph
srph / parser.ts
Created November 25, 2022 17:27
Stride: stride.vesting.StridePeriodicVestingAccount
import { Pubkey } from '@cosmjs/amino'
import { Uint64 } from '@cosmjs/math'
import { decodePubkey } from '@cosmjs/proto-signing'
import { assert } from '@cosmjs/utils'
import { stride } from '@stride/proto'
import { BaseAccount, ModuleAccount } from 'cosmjs-types/cosmos/auth/v1beta1/auth'
import {
BaseVestingAccount,
ContinuousVestingAccount,
DelayedVestingAccount,
@srph
srph / index.ts
Created November 15, 2022 05:05
date-fns: Convert duration months to days
import { intervalToDuration, isAfter, eachDayOfInterval, addMonths } from 'date-fns'
const remaining = intervalToDuration({
start: now,
end: target
})
const days =
remaining.months && remaining.days
? remaining.days +
@srph
srph / auth0.tsx
Created November 12, 2022 04:46
auth0-nextjs: Authorize by role
export const getServerSideProps = withPageAuthRequired({
async getServerSideProps(ctx) {
const whitelisted = ['[email protected]']
const session = getSession(ctx.req, ctx.res)
if (!whitelisted.includes(session.user.email)) {
return {
redirect: {
destination: '/logout',
@srph
srph / useMount.ts
Created July 18, 2022 13:01
React: useMount that works with Suspense / Fast Refresh
import { useEffect, useRef } from 'react'
// useEffect that runs on mount and works with Suspense / Fast Refresh
const useMount = (fn: () => void) => {
const isMountedRef = useRef(false)
useEffect(() => {
if (isMountedRef.current) return
isMountedRef.current = true
fn()
@srph
srph / poll.ts
Last active August 9, 2022 15:18
JS: Polling
import { delay } from './time'
export async function poll<T = any>(callback: () => Promise<T>, condition: (t: T) => boolean, ms: number): Promise<T> {
let first = true
while (true) {
const data = first ? await callback() : await delay(ms).then(callback)
if (condition(data) === true) {
return data
@srph
srph / Memoize.tsx
Created July 10, 2022 09:29
React: Inline useMemo
import React, { useState, useEffect } from 'react'
interface MemoizeProps<T, Y extends unknown> {
value: () => T
dependencies: Y[]
}
const Memoize = ({ value, dependencies }) => {
const [state, setState] = useState(value)
@srph
srph / index.ts
Last active June 20, 2022 07:34
Next.js: Active link
const { pathname } = useRouter()
const active: Record<string, boolean> = useMemo(() => {
return [
{ key: 'home', url: '/' },
{ key: 'about', url: '/about' },
{ key: 'contact', url: '/contact' }
].reduce((object, link) => {
object[link.key] = pathname === link.url
return object