migu/common/modules/util.js
2024-08-10 21:31:59 +07:00

177 lines
4.9 KiB
JavaScript

import { SUPPORTS } from '@/modules/support.js'
export function countdown (s) {
const d = Math.floor(s / (3600 * 24))
s -= d * 3600 * 24
const h = Math.floor(s / 3600)
s -= h * 3600
const m = Math.floor(s / 60)
s -= m * 60
const tmp = []
if (d) tmp.push(d + 'd')
if (d || h) tmp.push(h + 'h')
if (d || h || m) tmp.push(m + 'm')
return tmp.join(' ')
}
const formatter = (typeof Intl !== 'undefined') && new Intl.RelativeTimeFormat('en')
const ranges = {
years: 3600 * 24 * 365,
months: 3600 * 24 * 30,
weeks: 3600 * 24 * 7,
days: 3600 * 24,
hours: 3600,
minutes: 60,
seconds: 1
}
/**
* @template T
* @param {T[]} arr
* @param {number} n
*/
export function * chunks (arr, n) {
for (let i = 0; i < arr.length; i += n) {
yield arr.slice(i, i + n)
}
}
/** @param {Date} date */
export function since (date) {
const secondsElapsed = (date.getTime() - Date.now()) / 1000
for (const key in ranges) {
if (ranges[key] < Math.abs(secondsElapsed)) {
const delta = secondsElapsed / ranges[key]
// @ts-ignore
return formatter.format(Math.round(delta), key)
}
}
}
const units = [' B', ' kB', ' MB', ' GB', ' TB']
export function fastPrettyBytes (num) {
if (isNaN(num)) return '0 B'
if (num < 1) return num + ' B'
const exponent = Math.min(Math.floor(Math.log(num) / Math.log(1000)), units.length - 1)
return Number((num / Math.pow(1000, exponent)).toFixed(2)) + units[exponent]
}
/** @type {DOMParser['parseFromString']} */
export const DOMPARSER = (typeof DOMParser !== 'undefined') && DOMParser.prototype.parseFromString.bind(new DOMParser())
export const sleep = t => new Promise(resolve => setTimeout(resolve, t).unref?.())
export function toTS (sec, full) {
if (isNaN(sec) || sec < 0) {
switch (full) {
case 1:
return '0:00:00.00'
case 2:
return '0:00:00'
case 3:
return '00:00'
default:
return '0:00'
}
}
const hours = Math.floor(sec / 3600)
/** @type {any} */
let minutes = Math.floor(sec / 60) - hours * 60
/** @type {any} */
let seconds = full === 1 ? (sec % 60).toFixed(2) : Math.floor(sec % 60)
if (minutes < 10 && (hours > 0 || full)) minutes = '0' + minutes
if (seconds < 10) seconds = '0' + seconds
return (hours > 0 || full === 1 || full === 2) ? hours + ':' + minutes + ':' + seconds : minutes + ':' + seconds
}
export function generateRandomHexCode (len) {
let hexCode = ''
while (hexCode.length < len) {
hexCode += (Math.round(Math.random() * 15)).toString(16)
}
return hexCode
}
export function throttle (fn, time) {
let wait = false
return (...args) => {
if (!wait) {
fn(...args)
wait = true
setTimeout(() => {
fn(...args)
wait = false
}, time).unref?.()
}
}
}
export function debounce (fn, time) {
let timeout
return (...args) => {
const later = () => {
timeout = null
fn(...args)
}
clearTimeout(timeout)
timeout = setTimeout(later, time)
timeout.unref?.()
}
}
export const defaults = {
volume: 1,
playerAutoplay: true,
playerPause: true,
playerAutocomplete: true,
playerAutoSkip: false,
playerDeband: false,
playerSeek: 5,
rssQuality: '1080',
rssFeedsNew: SUPPORTS.extensions ? [['New Releases', 'ASW [Small Size]']] : [],
rssAutoplay: false,
torrentSpeed: 5, // legacy
downloadSpeed: 5,
uploadSpeed: 1,
slowSeeding: true,
disableStartupVideo: true,
amoledTheme: true,
enableAutoUpdate: true,
sortByEco: true,
torrentPersist: false,
torrentDHT: false,
torrentPeX: false,
torrentPort: 0,
torrentStreamedDownload: true,
dhtPort: 0,
missingFont: true,
maxConns: 50,
subtitleRenderHeight: SUPPORTS.isAndroid ? '1080' : '0',
subtitleLanguage: 'eng',
audioLanguage: 'jpn',
enableDoH: false,
doHURL: 'https://cloudflare-dns.com/dns-query',
disableSubtitleBlur: SUPPORTS.isAndroid,
enableRPC: false,
showDetailsInRPC: true,
smoothScroll: false,
cards: 'small',
expandingSidebar: !SUPPORTS.isAndroid,
torrentPathNew: undefined,
font: undefined,
angle: 'default',
toshoURL: SUPPORTS.extensions ? decodeURIComponent(atob('aHR0cHM6Ly9mZWVkLmFuaW1ldG9zaG8ub3JnLw==')) : '',
extensions: SUPPORTS.extensions ? ['@thaunknown/ani-resourced'] : [],
sources: {}
}
export const subtitleExtensions = ['srt', 'vtt', 'ass', 'ssa', 'sub', 'txt']
export const subRx = new RegExp(`.(${subtitleExtensions.join('|')})$`, 'i')
export const videoExtensions = ['3g2', '3gp', 'asf', 'avi', 'dv', 'flv', 'gxf', 'm2ts', 'm4a', 'm4b', 'm4p', 'm4r', 'm4v', 'mkv', 'mov', 'mp4', 'mpd', 'mpeg', 'mpg', 'mxf', 'nut', 'ogm', 'ogv', 'swf', 'ts', 'vob', 'webm', 'wmv', 'wtv']
export const videoRx = new RegExp(`.(${videoExtensions.join('|')})$`, 'i')
// freetype supported
export const fontExtensions = ['ttf', 'ttc', 'woff', 'woff2', 'otf', 'cff', 'otc', 'pfa', 'pfb', 'pcf', 'fnt', 'bdf', 'pfr', 'eot']
export const fontRx = new RegExp(`.(${fontExtensions.join('|')})$`, 'i')