forked from transitive-bullshit/nextjs-notion-starter-kit
-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathReactUtterances.tsx
110 lines (93 loc) · 2.79 KB
/
ReactUtterances.tsx
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
100
101
102
103
104
105
106
107
108
109
110
import React from 'react'
import styles from './styles.module.css'
export type MappingType =
| 'pathname'
| 'url'
| 'title'
| 'og:title'
| 'issue-number'
| 'issue-term'
export type Theme =
| 'github-light'
| 'github-dark'
| 'preferred-color-scheme'
| 'github-dark-orange'
| 'icy-dark'
| 'dark-blue'
| 'photon-dark'
interface ReactUtterancesProps {
repo: string
issueMap: MappingType
issueTerm?: string
issueNumber?: number
label?: string
theme: Theme
}
interface ReactUtterancesState {
pending: boolean
}
export class ReactUtterances extends React.Component<
ReactUtterancesProps,
ReactUtterancesState
> {
reference: React.RefObject<HTMLDivElement>
scriptElement: any
constructor(props: ReactUtterancesProps) {
super(props)
if (props.issueMap === 'issue-term' && props.issueTerm === undefined) {
throw Error(
"Property 'issueTerm' must be provided with issueMap 'issue-term'"
)
}
if (props.issueMap === 'issue-number' && props.issueNumber === undefined) {
throw Error(
"Property 'issueNumber' must be provided with issueMap 'issue-number'"
)
}
this.reference = React.createRef<HTMLDivElement>()
this.state = { pending: true }
}
UNSAFE_componentWillReceiveProps(props) {
// this.scriptElement.setAttribute('theme', props.theme)
const iframe = document.querySelector('iframe.utterances-frame') as any
if (iframe) {
iframe.contentWindow.postMessage(
{ type: 'set-theme', theme: props.theme },
'https://utteranc.es/'
)
}
}
componentDidMount(): void {
const { repo, issueMap, issueTerm, issueNumber, label, theme } = this.props
const scriptElement = document.createElement('script')
scriptElement.src = 'https://utteranc.es/client.js'
scriptElement.async = true
scriptElement.defer = true
scriptElement.setAttribute('repo', repo)
scriptElement.setAttribute('crossorigin', 'annonymous')
scriptElement.setAttribute('theme', theme)
scriptElement.onload = () => this.setState({ pending: false })
if (label) {
scriptElement.setAttribute('label', label)
}
if (issueMap === 'issue-number') {
scriptElement.setAttribute('issue-number', issueNumber.toString())
} else if (issueMap === 'issue-term') {
scriptElement.setAttribute('issue-term', issueTerm)
} else {
scriptElement.setAttribute('issue-term', issueMap)
}
// TODO: Check current availability
this.scriptElement = scriptElement
this.reference.current.appendChild(scriptElement)
}
render(): React.ReactElement {
return (
<div className={styles.comments}>
<div className={styles.utterances} ref={this.reference}>
{this.state.pending && <p>Loading Comments...</p>}
</div>
</div>
)
}
}