You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
2.1 KiB
JavaScript

import { toChildArray } from 'preact'
import { useCallback, useEffect, useState } from 'preact/hooks'
export function hashCode(s) {
s = s.toString() + "seed iniziale dell'hash"
let hash = 0
if (s.length === 0) return hash
for (let i = 0; i < s.length; i++) {
const chr = s.charCodeAt(i)
hash = (hash << 5) - hash + chr
hash |= 0
}
return Math.abs(hash)
}
export function useUser(onLoginStateChanged) {
const [user, setUser] = useState(null)
useEffect(() => {
fetch('/api/current-user')
.then(res => res.json())
.then(value => {
setUser(value)
onLoginStateChanged(value)
})
.catch(e => console.error(e))
}, [])
return user
}
//
// Hooks
//
// Router
function matchPattern(pattern, url) {
const r = `^${pattern.replace(/:([a-zA-Z0-9\_\-]+)/g, '(?<$1>[^\\/\\?]+?)')}$`
return new RegExp(r).exec(url)
}
export const useRouter = routes => {
for (const [id, route] of Object.entries(routes)) {
const m = matchPattern(route.pattern, location.pathname)
if (m) {
return [id, route, m.groups]
}
}
return ['unknown', { id: 'unknown' }, {}]
}
// useRemoteState
export function useRemoteState(url, initialValue = null) {
const [error, setError] = useState(null)
const [value, setValue] = useState(initialValue)
const refresh = async () => {
try {
const res = await fetch(url)
if (!res.ok) {
setError(await res.text())
return
}
setValue(await res.json())
} catch (err) {
setError(err)
}
}
useEffect(() => {
refresh()
}, [])
return [value, error, refresh]
}
//
// Change Case Utility
//
const fromCaseMap = {
camel: s => s.split(/(?=[A-Z])/),
// ...
}
const toCaseMap = {
dash: parts => parts.map(p => p.toLowerCase()).join('-'),
// ...
}
export function changeCase(from, to, s) {
return toCaseMap[to](fromCaseMap[from](s))
}