aboutsummaryrefslogblamecommitdiffhomepage
path: root/client/src/app/shared/misc/utils.ts
blob: f26240d216eee3461aab8d85eb20f12326d386b0 (plain) (tree)
1
2
3
4
5
6

                                                                                                     
                                          
                                                               

                                             












                                                               
                                                                                                                                









                                                            
                                                                                                          






                      









                                           




                                           











                                                                                                         



                                                        








                                                                          

                                                                           
                                   

             
                                       




                                                   




                                                           
                                                                                               
                                               







                                    
                                                                  
                               
                                                         


    





                                            




                                                         










                                                           



                         


































                                                                                           
        
         
                   
                 
                     
                     
                                 

                    
                  
                   
                       
                         
               
             
 
// Thanks: https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript

import { DatePipe } from '@angular/common'
import { environment } from '../../../environments/environment'
import { AuthService } from '../../core/auth'

function getParameterByName (name: string, url: string) {
  if (!url) url = window.location.href
  name = name.replace(/[\[\]]/g, '\\$&')

  const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)')
  const results = regex.exec(url)

  if (!results) return null
  if (!results[2]) return ''

  return decodeURIComponent(results[2].replace(/\+/g, ' '))
}

function populateAsyncUserVideoChannels (authService: AuthService, channel: { id: number, label: string, support?: string }[]) {
  return new Promise(res => {
    authService.userInformationLoaded
      .subscribe(
        () => {
          const user = authService.getUser()
          if (!user) return

          const videoChannels = user.videoChannels
          if (Array.isArray(videoChannels) === false) return

          videoChannels.forEach(c => channel.push({ id: c.id, label: c.displayName, support: c.support }))

          return res()
        }
      )
  })
}

function getAbsoluteAPIUrl () {
  let absoluteAPIUrl = environment.apiUrl
  if (!absoluteAPIUrl) {
    // The API is on the same domain
    absoluteAPIUrl = window.location.origin
  }

  return absoluteAPIUrl
}

const datePipe = new DatePipe('en')
function dateToHuman (date: string) {
  return datePipe.transform(date, 'medium')
}

function durationToString (duration: number) {
  const hours = Math.floor(duration / 3600)
  const minutes = Math.floor((duration % 3600) / 60)
  const seconds = duration % 60

  const minutesPadding = minutes >= 10 ? '' : '0'
  const secondsPadding = seconds >= 10 ? '' : '0'
  const displayedHours = hours > 0 ? hours.toString() + ':' : ''

  return displayedHours + minutesPadding + minutes.toString() + ':' + secondsPadding + seconds.toString()
}

function immutableAssign <A, B> (target: A, source: B) {
  return Object.assign({}, target, source)
}

function objectToUrlEncoded (obj: any) {
  const str: string[] = []
  for (const key of Object.keys(obj)) {
    str.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]))
  }

  return str.join('&')
}

// Thanks: https://gist.github.com/ghinda/8442a57f22099bdb2e34
function objectToFormData (obj: any, form?: FormData, namespace?: string) {
  const fd = form || new FormData()
  let formKey

  for (const key of Object.keys(obj)) {
    if (namespace) formKey = `${namespace}[${key}]`
    else formKey = key

    if (obj[key] === undefined) continue

    if (Array.isArray(obj[key]) && obj[key].length === 0) {
      fd.append(key, null)
      continue
    }

    if (obj[key] !== null && typeof obj[ key ] === 'object' && !(obj[ key ] instanceof File)) {
      objectToFormData(obj[ key ], fd, formKey)
    } else {
      fd.append(formKey, obj[ key ])
    }
  }

  return fd
}

function objectLineFeedToHtml (obj: any, keyToNormalize: string) {
  return immutableAssign(obj, {
    [keyToNormalize]: lineFeedToHtml(obj[keyToNormalize])
  })
}

function lineFeedToHtml (text: string) {
  if (!text) return text

  return text.replace(/\r?\n|\r/g, '<br />')
}

function removeElementFromArray <T> (arr: T[], elem: T) {
  const index = arr.indexOf(elem)
  if (index !== -1) arr.splice(index, 1)
}

function sortBy (obj: any[], key1: string, key2?: string) {
  return obj.sort((a, b) => {
    const elem1 = key2 ? a[key1][key2] : a[key1]
    const elem2 = key2 ? b[key1][key2] : b[key1]

    if (elem1 < elem2) return -1
    if (elem1 === elem2) return 0
    return 1
  })
}

function scrollToTop () {
  window.scroll(0, 0)
}

// Thanks: https://github.com/uupaa/dynamic-import-polyfill
function importModule (path: string) {
  return new Promise((resolve, reject) => {
    const vector = '$importModule$' + Math.random().toString(32).slice(2)
    const script = document.createElement('script')

    const destructor = () => {
      delete window[ vector ]
      script.onerror = null
      script.onload = null
      script.remove()
      URL.revokeObjectURL(script.src)
      script.src = ''
    }

    script.defer = true
    script.type = 'module'

    script.onerror = () => {
      reject(new Error(`Failed to import: ${path}`))
      destructor()
    }
    script.onload = () => {
      resolve(window[ vector ])
      destructor()
    }
    const absURL = (environment.apiUrl || window.location.origin) + path
    const loader = `import * as m from "${absURL}"; window.${vector} = m;` // export Module
    const blob = new Blob([ loader ], { type: 'text/javascript' })
    script.src = URL.createObjectURL(blob)

    document.head.appendChild(script)
  })
}

export {
  sortBy,
  durationToString,
  lineFeedToHtml,
  objectToUrlEncoded,
  getParameterByName,
  populateAsyncUserVideoChannels,
  getAbsoluteAPIUrl,
  dateToHuman,
  immutableAssign,
  objectToFormData,
  objectLineFeedToHtml,
  removeElementFromArray,
  importModule,
  scrollToTop
}