zaphyra's git: domsonic

subsonic web-client

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 
import type { Track } from './types'

export const isMobile = () => (
  matchMedia('(pointer: coarse)').matches 
  && (navigator.maxTouchPoints > 0)
)

export const randomString = (): string => {
  let arr = new Uint8Array(16)
  window.crypto.getRandomValues(arr)
  const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  arr = arr.map(x => validChars.charCodeAt(x % validChars.length))
  return String.fromCharCode.apply(null, Array.from(arr))
}

export const shuffle = (list: any[], moveFirst?: number): void => {
  if (moveFirst !== undefined)
    [list[0], list[moveFirst]] = [list[moveFirst], list[0]]

  const
    end = list.length - 1,
    start = (
      (moveFirst !== undefined)
      ? 1
      : 0
    )

  for (let i = end; i > start; i--) {
    const j = Math.floor(Math.random() * (i - start + 1) + start);
    [list[i], list[j]] = [list[j], list[i]]
  }
}

export const shuffled = (list: any[], moveFirst?: number): any[] => {
  list = [...list]
  shuffle(list, moveFirst)
  return list
}

export const trackListEquals = (a: Track[], b: Track[]): boolean => {
  if (a.length !== b.length)
    return false

  for (let i = 0; i < a.length; i++) {
    if (a[i]?.id !== b[i]?.id) return false
  }

  return true
}

export const formatArtists = (artists: { name: string }[]): string => artists.map(ar => ar.name).join(', ')

export const formatTitle = (title: string): string => (
  (!title)
  ? ''
  : (
    (title.length > 40)
    ? title.slice(0, 37) + '…'
    : title
  )
)

export const formatDuration = (value: number): string => {
  if (!isFinite(value))
    return '∞'

  const
    minutes = Math.floor(value / 60),
    seconds = Math.floor(value % 60)

  return `${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}

export const formatBytes = (bytes: number, decimals: number): string => {
  if (bytes === 0) return '0 Bytes';

  const
    k = 1024,
    i = Math.floor(Math.log(bytes) / Math.log(k)),
    unit = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'][i];

  return `${parseFloat((bytes / Math.pow(k, i)).toFixed(decimals || 2))} ${unit}`;
}

export const sleep = async (ms: number) => new Promise(
  resolve => setTimeout(resolve, ms)
)

export const isElementInViewport = (element: HTMLElement | null) => {
  if (!element) return false

  const rect = element.getBoundingClientRect()
  return (
    rect.bottom >= 0 &&
    rect.right >= 0 &&
    rect.top <= (window.innerHeight || document.documentElement.clientHeight) &&
    rect.left <= (window.innerWidth || document.documentElement.clientWidth)
  )
}