summaryrefslogtreecommitdiff
path: root/client/util/index.js
blob: e90e5466324d7fe0a50b1c9d2fbe177e4fca5e05 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/* 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
export const isFirefox = typeof InstallTrigger !== 'undefined'

export const toArray = a => Array.prototype.slice.apply(a)
export const choice = a => a[Math.floor(Math.random() * a.length)]
export const toTuples = o => Object.keys(o).map(key => [key, o[key]])

const htmlClassList = document.body.parentNode.classList
htmlClassList.add(isDesktop ? 'desktop' : 'mobile')
if (isFirefox) {
  htmlClassList.add('firefox')
}

/* 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, b) => n < a ? a : n < b ? n : b

export const domainFromUrl = url => {
  const partz = url.split('/')[2].split('.')
  if (partz.length > 2 && partz[partz.length - 2].length == 2) {
    return partz.slice(-3).join('.')
  } else {
    return partz.slice(-2).join('.')
  }
}

/* URLs */

export const preloadImage = opt => {
  let { verified, hash, frame, url } = opt
  if (hash && frame) {
    url = imageUrl(verified, hash, frame, 'md')
  }
  const image = new Image()
  let loaded = false
  image.onload = () => {
    if (loaded) return
    loaded = true
    image.onload = null
  }
  // console.log(img.src)
  image.crossOrigin = 'anonymous'
  image.src = url
  if (image.complete) {
    image.onload()
  }
}

/* AJAX */

export const get = (uri, data) => {
  let headers = {
    Accept: 'application/json, application/xml, text/play, text/html, *.*',
  }
  let opt = {
    method: 'GET',
    body: data,
    headers,
    // credentials: 'include',
  }
  // console.log(headers)
  // headers['X-CSRFToken'] = csrftoken
  return fetch(uri, opt).then(res => res.json())
}

export const post = (uri, data) => {
  let headers
  if (data instanceof FormData) {
    headers = {
      Accept: 'application/json, application/xml, text/play, text/html, *.*',
    }
  } else {
    headers = {
      Accept: 'application/json, application/xml, text/play, text/html, *.*',
      'Content-Type': 'application/json; charset=utf-8',
    }
    data = JSON.stringify(data)
  }
  let opt = {
    method: 'POST',
    body: data,
    headers,
    // credentials: 'include',
  }
  // console.log(headers)
  // headers['X-CSRFToken'] = csrftoken
  return fetch(uri, opt).then(res => res.json())
}