summaryrefslogtreecommitdiff
path: root/frontend/util/index.js
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2020-09-26 14:56:02 +0200
committerJules Laplace <julescarbon@gmail.com>2020-09-26 14:56:02 +0200
commita17b76ac75f506f5da6fe8adf9c36632b60d4226 (patch)
treeabb0af0c4409b830dea2ef808c146223ee973933 /frontend/util/index.js
parent2231a6e1c05b07bb7ec5906716aedec93d02429c (diff)
refactor to use app-rooted js imports
Diffstat (limited to 'frontend/util/index.js')
-rw-r--r--frontend/util/index.js331
1 files changed, 0 insertions, 331 deletions
diff --git a/frontend/util/index.js b/frontend/util/index.js
deleted file mode 100644
index 194ecf0..0000000
--- a/frontend/util/index.js
+++ /dev/null
@@ -1,331 +0,0 @@
-import { api as api_type } from '../types'
-
-// import { format, formatDistance } from 'date-fns'
-import format from 'date-fns/format'
-import formatDistance from 'date-fns/formatDistance'
-
-export const formatDateTime = dateStr => format(new Date(dateStr), 'd MMM yyyy H:mm')
-export const formatDate = dateStr => format(new Date(dateStr), 'd MMM yyyy')
-export const formatTime = dateStr => format(new Date(dateStr), 'H:mm')
-export const formatAge = dateStr => formatDistance(new Date(), new Date(dateStr)) + ' ago.'
-
-/* Mobile check */
-
-export const isiPhone = !!((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)))
-export const isiPad = !!(navigator.userAgent.match(/iPad/i))
-export const isAndroid = !!(navigator.userAgent.match(/Android/i))
-export const isMobile = isiPhone || isiPad || isAndroid
-export const isDesktop = !isMobile
-
-const htmlClassList = document.body.parentNode.classList
-htmlClassList.add(isDesktop ? 'desktop' : 'mobile')
-
-/* Default image dimensions */
-
-export const widths = {
- th: 160,
- sm: 320,
- md: 640,
- lg: 1280,
-}
-
-/* Formatting functions */
-
-const acronyms = 'id url cc sa fp md5 sha256'.split(' ').map(s => '_' + s)
-const acronymsUpperCase = acronyms.map(s => s.toUpperCase())
-
-export const formatName = s => {
- acronyms.forEach((acronym, i) => s = s.replace(acronym, acronymsUpperCase[i]))
- return s.replace(/_/g, ' ')
-}
-
-// Use to pad frame numbers with zeroes
-export const pad = (n, m) => {
- let s = String(n || 0)
- while (s.length < m) {
- s = '0' + s
- }
- return s
-}
-
-export const courtesyS = (n, s) => n + ' ' + (n === 1 ? s : s + 's')
-
-export const padSeconds = n => n < 10 ? '0' + n : n
-
-export const timestamp = (n = 0, fps = 25) => {
- n /= fps
- let s = padSeconds(Math.round(n) % 60)
- n = Math.floor(n / 60)
- if (n > 60) {
- return Math.floor(n / 60) + ':' + padSeconds(n % 60) + ':' + s
- }
- return (n % 60) + ':' + s
-}
-
-export const percent = n => (n * 100).toFixed(1) + '%'
-
-export const px = (n, w) => Math.round(n * w) + 'px'
-
-export const clamp = (n, a=0, b=1) => n < a ? a : n < b ? n : b
-export const dist = (x1, y1, x2, y2) => Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))
-export const mod = (n, m) => n - (m * Math.floor(n / m))
-export const angle = (x1, y1, x2, y2) => Math.atan2(y2 - y1, x2 - x1)
-
-/* URLs */
-
-export const sha256_tree = (sha256, branch_size=2, tree_depth=2) => {
- const tree_size = tree_depth * branch_size
- let tree = ""
- for (var i = 0; i < tree_size; i += branch_size) {
- tree += '/' + sha256.substr(i, branch_size)
- }
- return tree
-}
-
-export const imageUrl = (sha256, frame, size = 'th') => [
- 'https://' + process.env.S3_HOST + '/v1/media/keyframes',
- sha256_tree(sha256),
- pad(frame, 6),
- size,
- 'index.jpg'
-].filter(s => !!s).join('/')
-
-export const uploadUri = ({ sha256, ext }) => '/static/data/uploads' + sha256_tree(sha256) + '/' + sha256 + ext
-export const metadataUri = (sha256, tag) => '/metadata/' + sha256 + '/' + tag + '/'
-export const keyframeUri = (sha256, frame) => '/metadata/' + sha256 + '/keyframe/' + pad(frame, 6) + '/'
-
-export const preloadImage = url => (
- new Promise((resolve, reject) => {
- const image = new Image()
- let loaded = false
- image.onload = () => {
- if (loaded) return
- loaded = true
- image.onload = null
- image.onerror = null
- resolve(image)
- }
- image.onerror = () => {
- if (loaded) return
- image.onload = null
- image.onerror = null
- resolve(image)
- }
- // console.log(img.src)
- // image.crossOrigin = 'anonymous'
- image.src = url
- if (image.complete) {
- image.onload()
- }
- })
-)
-
-export const cropImage = (url, crop) => {
- return new Promise((resolve, reject) => {
- let { x, y, w, h } = crop
- const image = new Image()
- let loaded = false
- x = parseFloat(x)
- y = parseFloat(y)
- w = parseFloat(w)
- h = parseFloat(h)
- image.onload = () => {
- if (loaded) return
- loaded = true
- image.onload = null
- const canvas = document.createElement('canvas')
- const ctx = canvas.getContext('2d')
- const width = image.naturalWidth
- const height = image.naturalHeight
- canvas.width = w * width
- canvas.height = h * height
- ctx.drawImage(
- image,
- Math.round(x * width),
- Math.round(y * height),
- Math.round(w * width),
- Math.round(h * height),
- 0, 0, canvas.width, canvas.height
- )
- resolve(canvas)
- }
- image.onerror = () => {
- console.log('image error')
- reject()
- }
- // console.log(img.src)
- image.crossOrigin = 'anonymous'
- image.src = url
- if (image.complete) {
- image.onload()
- }
- })
-}
-export const urlSearchParamsToDict = search => {
- const params = new URLSearchParams(search)
- const dict = {}
- params.forEach((value, key) => { // ???
- dict[key] = value
- })
- return dict
-}
-
-/* AJAX */
-
-let cachedAuth = null
-let token = ''
-let username = ''
-
-export const post = (dispatch, type=api_type, tag, url, data) => {
- let headers
- if (data instanceof FormData) {
- headers = {
- Accept: 'application/json',
- }
- } else if (data) {
- headers = {
- Accept: 'application/json',
- 'Content-Type': 'application/json; charset=utf-8',
- }
- data = JSON.stringify(data)
- }
-
- dispatch({
- type: type.loading,
- tag,
- })
- return fetch(url, {
- method: 'POST',
- body: data,
- headers,
- })
- .then(res => res.json())
- .then(res => dispatch({
- type: type.loaded,
- tag,
- data: res,
- }))
- .catch(err => dispatch({
- type: type.error,
- tag,
- err,
- }))
-}
-
-export const api = (dispatch, type=api_type, tag, url, data) => {
- dispatch({
- type: type.loading,
- tag,
- })
- if (url.indexOf('http') !== 0) {
- url = window.location.origin + url
- }
- url = new URL(url)
- if (data) {
- url.search = new URLSearchParams(data).toString()
- }
- return fetch(url, {
- method: 'GET',
- // mode: 'cors',
- })
- .then(res => res.json())
- .then(res => dispatch({
- type: type.loaded,
- tag,
- data: res,
- }))
- .catch(err => dispatch({
- type: type.error,
- tag,
- err,
- }))
-}
-
-/* sorting */
-
-export const numericSort = {
- asc: (a,b) => a[0] - b[0],
- desc: (a,b) => b[0] - a[0],
-}
-export const stringSort = {
- asc: (a,b) => a[0].localeCompare(b[0]),
- desc: (a,b) => b[0].localeCompare(a[0]),
-}
-export const orderByFn = (s='name asc') => {
- const [field='name', direction='asc'] = s.split(' ')
- let mapFn, sortFn
- switch (field) {
- case 'id':
- mapFn = a => [parseInt(a.id) || 0, a]
- sortFn = numericSort[direction]
- break
- case 'epoch':
- mapFn = a => [parseInt(a.epoch || a.epochs) || 0, a]
- sortFn = numericSort[direction]
- break
- case 'size':
- mapFn = a => [parseInt(a.size) || 0, a]
- sortFn = numericSort[direction]
- break
- case 'date':
- mapFn = a => [+new Date(a.date || a.created_at), a]
- sortFn = numericSort[direction]
- break
- case 'updated_at':
- mapFn = a => [+new Date(a.updated_at), a]
- sortFn = numericSort[direction]
- break
- case 'priority':
- mapFn = a => [parseInt(a.priority) || parseInt(a.id) || 1000, a]
- sortFn = numericSort[direction]
- case 'name':
- default:
- mapFn = a => [a.name || "", a]
- sortFn = stringSort[direction]
- break
- }
- return { mapFn, sortFn }
-}
-export const getOrderedIds = (objects, sort, prepend=[]) => {
- const { mapFn, sortFn } = orderByFn(sort)
- return prepend.concat(objects.map(mapFn).sort(sortFn).map(a => a[1].id))
-}
-export const getOrderedIdsFromLookup = (lookup, sort) => {
- return getOrderedIds(Object.keys(lookup).map(key => lookup[key]), sort)
-}
-
-/* parallel promises */
-
-export const allProgress = (promises, progress_cb) => {
- let d = 0
- progress_cb(0, 0, promises.length)
- promises.forEach((p) => {
- p.then((s) => {
- d += 1
- progress_cb(Math.floor((d * 100) / promises.length), d, promises.length)
- return s
- })
- })
- return Promise.all(promises)
-}
-
-/* Clipboard */
-
-export function writeToClipboard(str) {
- return new Promise((resolve, reject) => {
- let success = false
- function listener(e) {
- e.clipboardData.setData("text/plain", str)
- e.preventDefault()
- success = true
- }
- document.addEventListener("copy", listener)
- document.execCommand("copy")
- document.removeEventListener("copy", listener)
- if (success) {
- resolve()
- } else {
- reject()
- }
- })
-} \ No newline at end of file