deemix-webui/src/utils/utils.js
2021-07-17 14:28:29 +02:00

159 lines
3.3 KiB
JavaScript

/**
* Climbs the DOM until the root is reached, storing every node passed.
* @param {HTMLElement} el
* @return {Array} Contains all the nodes between el and the root
* @since 0.0.0
*/
export function generatePath(el) {
if (!el) {
throw new Error('No element passed to the generatePath function!')
}
const path = [el]
while ((el = el.parentNode) && el !== document) {
path.push(el)
}
return path
}
/**
* @param {string} text
* @returns {boolean}
* @since 0.0.0
*/
export function isValidURL(text) {
const lowerCaseText = text.toLowerCase()
if (lowerCaseText.startsWith('http')) {
if (
lowerCaseText.includes('deezer.com') ||
lowerCaseText.includes('deezer.page.link') ||
lowerCaseText.includes('open.spotify.com') ||
lowerCaseText.includes('link.tospotify.com')
) {
return true
}
} else if (lowerCaseText.startsWith('spotify:')) {
return true
}
return false
}
/**
* @param {number} duration
* @returns {string}
* @since 0.0.0
*/
export function convertDuration(duration) {
const mm = Math.floor(duration / 60)
// Convert from seconds only to mm:ss format
let ss = duration - mm * 60 // Add leading zero if ss < 0
if (ss < 10) {
ss = '0' + ss
}
return mm + ':' + ss
}
/**
* @param {number} duration
* @returns {[number, number, number]}
* @since 0.0.0
*/
export function convertDurationSeparated(duration) {
let mm = Math.floor(duration / 60)
const hh = Math.floor(mm / 60)
const ss = duration - mm * 60
mm -= hh * 60
return [hh, mm, ss]
}
/**
* @param {number} x
* @returns {string}
* @since 0.0.0
* @deprecated
*/
export const numberWithDots = x => x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, '.')
// On scroll event, returns currentTarget = null
// Probably on other events too
export function debounce(func, wait, immediate) {
let timeout
return function () {
const context = this
const args = arguments
const later = function () {
timeout = null
if (!immediate) func.apply(context, args)
}
const callNow = immediate && !timeout
clearTimeout(timeout)
timeout = setTimeout(later, wait)
if (callNow) func.apply(context, args)
}
}
/**
* Workaround to copy to the clipboard cross-OS by generating a
* ghost input and copying the passed String
*
* @param {string} text Text to copy
* @returns void
* @since 0.0.0
*/
export function copyToClipboard(text) {
const ghostInput = document.createElement('input')
document.body.appendChild(ghostInput)
ghostInput.setAttribute('type', 'text')
ghostInput.setAttribute('value', text)
ghostInput.select()
ghostInput.setSelectionRange(0, 99999)
document.execCommand('copy')
ghostInput.remove()
}
/**
* @param {object|array} obj
* @param {...any} props
* @returns {any|null} property requested
* @since 0.0.0
*/
export function getPropertyWithFallback(obj, ...props) {
for (const prop of props) {
// Example: this.is.an.example
const hasDotNotation = /\./.test(prop)
// Searching the properties in the object
const valueToTest = hasDotNotation
? prop.split('.').reduce((o, i) => {
if (o) {
return o[i]
}
}, obj)
: obj[prop]
if (typeof valueToTest !== 'undefined') {
return valueToTest
}
}
return null
}
export default {
isValidURL,
convertDuration,
convertDurationSeparated,
numberWithDots,
debounce
}