forked from
jollywhoppers.com/witchsky.app
Bluesky app fork with some witchin' additions 馃挮
1import {useEffect, useState} from 'react'
2import {type I18n} from '@lingui/core'
3import {plural} from '@lingui/macro'
4
5export function displayDuration(i18n: I18n, durationInMinutes: number) {
6 const roundedDurationInMinutes = Math.round(durationInMinutes)
7 const hours = Math.floor(roundedDurationInMinutes / 60)
8 const minutes = roundedDurationInMinutes % 60
9 const minutesString = i18n._(
10 plural(minutes, {one: '# minute', other: '# minutes'}),
11 )
12 return hours > 0
13 ? i18n._(
14 minutes > 0
15 ? plural(hours, {
16 one: `# hour ${minutesString}`,
17 other: `# hours ${minutesString}`,
18 })
19 : plural(hours, {
20 one: '# hour',
21 other: '# hours',
22 }),
23 )
24 : minutesString
25}
26
27// Trailing debounce
28export function useDebouncedValue<T>(val: T, delayMs: number): T {
29 const [prev, setPrev] = useState(val)
30
31 useEffect(() => {
32 const timeout = setTimeout(() => setPrev(val), delayMs)
33 return () => clearTimeout(timeout)
34 }, [val, delayMs])
35
36 return prev
37}
38
39const serviceUrlToNameMap: Record<string, string> = {
40 'twitch.tv': 'Twitch',
41 'www.twitch.tv': 'Twitch',
42 'youtube.com': 'YouTube',
43 'www.youtube.com': 'YouTube',
44 'youtu.be': 'YouTube',
45 'nba.com': 'NBA',
46 'www.nba.com': 'NBA',
47 'nba.smart.link': 'nba.smart.link',
48 'espn.com': 'ESPN',
49 'www.espn.com': 'ESPN',
50 'stream.place': 'Streamplace',
51 'skylight.social': 'Skylight',
52 'bluecast.app': 'Bluecast',
53 'www.bluecast.app': 'Bluecast',
54}
55
56export function getLiveServiceNames(domains: Set<string>) {
57 const names = Array.from(
58 new Set(Array.from(domains.values()).map(d => serviceUrlToNameMap[d] || d)),
59 )
60 return {
61 names,
62 formatted: names.join(', '),
63 }
64}