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
|
import { createSignal, onCleanup, splitProps } from "solid-js"
import type { JSX } from "solid-js/jsx-runtime"
import { IconCheckCircle, IconHashtag } from "../icons"
interface AnchorProps extends JSX.HTMLAttributes<HTMLDivElement> {
id: string
}
export function AnchorIcon(props: AnchorProps) {
const [local, rest] = splitProps(props, ["id", "children"])
const [copied, setCopied] = createSignal(false)
return (
<div {...rest} data-element-anchor title="Link to this message" data-status={copied() ? "copied" : ""}>
<a
href={`#${local.id}`}
onClick={(e) => {
e.preventDefault()
const anchor = e.currentTarget
const hash = anchor.getAttribute("href") || ""
const { origin, pathname, search } = window.location
navigator.clipboard
.writeText(`${origin}${pathname}${search}${hash}`)
.catch((err) => console.error("Copy failed", err))
setCopied(true)
setTimeout(() => setCopied(false), 3000)
}}
>
{local.children}
<IconHashtag width={18} height={18} />
<IconCheckCircle width={18} height={18} />
</a>
<span data-element-tooltip>Copied!</span>
</div>
)
}
export function createOverflow() {
const [overflow, setOverflow] = createSignal(false)
return {
get status() {
return overflow()
},
ref(el: HTMLElement) {
const ro = new ResizeObserver(() => {
if (el.scrollHeight > el.clientHeight + 1) {
setOverflow(true)
}
return
})
ro.observe(el)
onCleanup(() => {
ro.disconnect()
})
},
}
}
export function formatDuration(ms: number): string {
const ONE_SECOND = 1000
const ONE_MINUTE = 60 * ONE_SECOND
if (ms >= ONE_MINUTE) {
const minutes = Math.floor(ms / ONE_MINUTE)
return minutes === 1 ? `1min` : `${minutes}mins`
}
if (ms >= ONE_SECOND) {
const seconds = Math.floor(ms / ONE_SECOND)
return `${seconds}s`
}
return `${ms}ms`
}
|