blob: ec4fa58dce06c0b77d178df444bb10d2f83c10d8 (
plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import React = require('react');
import ReactLoading from 'react-loading';
import Typist from 'react-typist';
import { Doc } from '../../../fields/Doc';
import { Docs } from '../../documents/Documents';
import './GPTPopup.scss';
interface GPTPopupProps {
visible: boolean;
text: string;
loadingSummary: boolean;
callApi: (e: React.PointerEvent) => Promise<void>;
}
@observer
export class GPTPopup extends React.Component<GPTPopupProps> {
static Instance: GPTPopup;
@observable
private summaryDone: boolean = false;
@observable
private sidebarId: string = '';
@action
public setSummaryDone = (done: boolean) => {
this.summaryDone = done;
};
@action
public setSidebarId = (id: string) => {
this.sidebarId = id;
};
public addDoc: (doc: Doc | Doc[], sidebarKey?: string | undefined) => boolean = () => false;
/**
* Transfers the summarization text to a sidebar annotation text document.
*/
private transferToText = () => {
const newDoc = Docs.Create.TextDocument(this.props.text.trim(), {
_width: 200,
_height: 50,
_fitWidth: true,
_autoHeight: true,
});
this.addDoc(newDoc, this.sidebarId);
};
constructor(props: GPTPopupProps) {
super(props);
GPTPopup.Instance = this;
}
componentDidUpdate = () => {
if (this.props.loadingSummary) {
this.setSummaryDone(false);
}
};
render() {
return (
<div className="summary-box" style={{ display: this.props.visible ? 'flex' : 'none' }}>
<div className="summary-heading">
<label className="summary-text">SUMMARY</label>
{this.props.loadingSummary && <ReactLoading type="spin" color="#bcbcbc" width={14} height={14} />}
</div>
<div className="content-wrapper">
{!this.props.loadingSummary &&
(!this.summaryDone ? (
<Typist
key={this.props.text}
avgTypingDelay={15}
cursor={{ hideWhenDone: true }}
onTypingDone={action(() => {
setTimeout(
action(() => {
this.summaryDone = true;
}),
500
);
})}>
{this.props.text}
</Typist>
) : (
this.props.text
))}
</div>
{!this.props.loadingSummary && (
<div className="btns-wrapper">
{this.summaryDone ? (
<>
<button className="icon-btn" onPointerDown={e => this.props.callApi(e)}>
<FontAwesomeIcon icon="redo-alt" size="lg" />
</button>
<button
className="text-btn"
onClick={e => {
this.transferToText();
}}>
Transfer to Text
</button>
</>
) : (
<div className="summarizing">
<label>Summarizing</label>
<ReactLoading type="bubbles" color="#bcbcbc" width={20} height={20} />
<button
className="btn-secondary"
onClick={e => {
this.setSummaryDone(true);
}}>
Stop Animation
</button>
</div>
)}
</div>
)}
{this.summaryDone && (
<div className="ai-warning">
<FontAwesomeIcon icon="exclamation-circle" size="sm" style={{ paddingRight: '5px' }} />
AI generated responses can contain inaccurate or misleading content.{' '}
<a target="_blank" href="https://www.nytimes.com/2023/02/08/technology/ai-chatbots-disinformation.html">
Learn More
</a>
</div>
)}
</div>
);
}
}
|