summaryrefslogtreecommitdiff
path: root/client/util.js
diff options
context:
space:
mode:
authorJules Laplace <julescarbon@gmail.com>2018-11-03 17:29:49 +0100
committerJules Laplace <julescarbon@gmail.com>2018-11-03 17:29:49 +0100
commitaa0470a3076f5ac65a0311c76e58254547f3eae0 (patch)
tree001173d70a0ae93d367773453cbdc9091bbc9fb7 /client/util.js
parent3e534be7b919bf402d3602fde5b45809201f06b1 (diff)
begin client
Diffstat (limited to 'client/util.js')
-rw-r--r--client/util.js167
1 files changed, 167 insertions, 0 deletions
diff --git a/client/util.js b/client/util.js
new file mode 100644
index 00000000..ad303c64
--- /dev/null
+++ b/client/util.js
@@ -0,0 +1,167 @@
+/* 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
+}
+
+// Verified is 0/1 when retrieved from SQL, but 'verified' or 'unverified' when retrieved elsewhere
+export const isVerified = verified => verified === 1 || verified === '1' || verified === 'verified'
+export const verify = verified => isVerified(verified) ? 'verified' : 'unverified'
+
+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
+
+/* URLs */
+
+export const hashPath = sha256 => {
+ if (!sha256 || sha256.length < 9) {
+ throw new Error('Invalid sha256')
+ }
+ return [
+ sha256.slice(0, 3),
+ sha256.slice(3, 6),
+ sha256.slice(6, 9),
+ sha256,
+ ].join('/')
+}
+
+export const imageUrl = (verified, sha256, frame, size = 'th') => [
+ 'https://' + process.env.S3_HOST + '/v1/media/keyframes',
+ isVerified(verified) ? null : 'unverified',
+ hashPath(sha256),
+ pad(frame, 6),
+ size,
+ 'index.jpg'
+].filter(s => !!s).join('/')
+
+export const metadataUri = (sha256, tag) => '/metadata/' + sha256 + '/' + tag + '/'
+export const keyframeUri = (sha256, frame) => '/metadata/' + sha256 + '/keyframe/' + pad(frame, 6) + '/'
+
+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 */
+
+let cachedAuth = null
+let token = ''
+let username = ''
+
+export const post = (uri, data, credentials) => {
+ login()
+ 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',
+ }
+ if (credentials) {
+ headers.Authorization = 'Token ' + token
+ }
+ // console.log(headers)
+ // headers['X-CSRFToken'] = csrftoken
+ return fetch(uri, opt).then(res => res.json())
+}
+
+// api queries
+export const login = () => {
+ if (cachedAuth) return cachedAuth
+ const isLocal = (window.location.hostname === '0.0.0.0' || window.location.hostname === '127.0.0.1')
+ try {
+ const auth = JSON.parse(JSON.parse(localStorage.getItem('persist:root')).auth)
+ // console.log('auth', auth)
+ token = auth.token
+ username = auth.user.username
+ if (token) {
+ console.log('logged in', username)
+ }
+ cachedAuth = auth
+ if (!token && !isLocal) {
+ window.location.href = '/'
+ }
+ return auth
+ } catch (e) {
+ if (!isLocal) {
+ window.location.href = '/'
+ }
+ return {}
+ }
+}