diff options
Diffstat (limited to 'src/client/views/pdf/PDFViewer.tsx')
-rw-r--r-- | src/client/views/pdf/PDFViewer.tsx | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/src/client/views/pdf/PDFViewer.tsx b/src/client/views/pdf/PDFViewer.tsx index dee0edfae..02d310f7d 100644 --- a/src/client/views/pdf/PDFViewer.tsx +++ b/src/client/views/pdf/PDFViewer.tsx @@ -28,6 +28,12 @@ import { AnchorMenu } from './AnchorMenu'; import { Annotation } from './Annotation'; import { GPTPopup } from './GPTPopup/GPTPopup'; import './PDFViewer.scss'; +import { GPTCallType, gptAPICall } from '../../apis/gpt/GPT'; +import ReactLoading from 'react-loading'; +// import html2canvas from 'html2canvas'; +// import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition'; + +// pdfjsLib.GlobalWorkerOptions.workerSrc = `/assets/pdf.worker.js`; // The workerSrc property shall be specified. // Pdfjs.GlobalWorkerOptions.workerSrc = 'https://unpkg.com/pdfjs-dist@4.4.168/build/pdf.worker.mjs'; @@ -58,12 +64,50 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { super(props); makeObservable(this); } + // @observable transcriptRef = React.createRef(); + // @observable startBtnRef = React.createRef(); + // @observable stopBtnRef = React.createRef(); + // @observable transcriptElement = ''; + + // handleResult = (e: SpeechRecognitionEvent) => { + // let interimTranscript = ''; + // let finalTranscript = ''; + // console.log('H'); + // for (let i = e.resultIndex; i < e.results.length; i++) { + // const transcript = e.results[i][0].transcript; + // if (e.results[i].isFinal) { + // finalTranscript += transcript; + // } else { + // interimTranscript += transcript; + // } + // } + // console.log(interimTranscript); + // this.transcriptElement = finalTranscript || interimTranscript; + // }; + + // startListening = () => { + // const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; + // if (SpeechRecognition) { + // console.log('here'); + // const recognition = new SpeechRecognition(); + // recognition.continuous = true; // Continue listening even if the user pauses + // recognition.interimResults = true; // Show interim results + // recognition.lang = 'en-US'; // Set language (optional) + // recognition.onresult = this.handleResult.bind(this); + // // recognition.onend = this.handleEnd.bind(this); + + // recognition.start(); + // // this.handleResult; + // // recognition.stop(); + // } + // }; @observable _pageSizes: { width: number; height: number }[] = []; @observable _savedAnnotations = new ObservableMap<number, (HTMLDivElement & { marqueeing?: boolean })[]>(); @observable _textSelecting = true; @observable _showWaiting = true; @observable Index: number = -1; + @observable private _loading = false; private _pdfViewer!: PDFJSViewer.PDFViewer; private _styleRule: number | undefined; // stylesheet rule for making hyperlinks clickable @@ -394,6 +438,122 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { } }; + gptPDFFlashcards = async () => { + // const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; + // if (SpeechRecognition) { + // this.recognition = new SpeechRecognition(); + // this.recognition.continuous = true; // Continue listening even if the user pauses + // this.recognition.interimResults = true; // Show interim results + // this.recognition.lang = 'en-US'; // Set language (optional) + + // this.recognition.onresult = this.handleResult; + // this.recognition.onerror = this.handleError; + // this.recognition.onend = this.handleEnd; + // } else { + // console.error("Browser doesn't support Speech Recognition API"); + // } + // const Dictaphone = () => { + // const { transcript, resetTranscript } = useSpeechRecognition(); + + // if (!SpeechRecognition.browserSupportsSpeechRecognition()) { + // return null; + // } + + // return ( + // <div> + // <button onClick={e => SpeechRecognition.startListening}>Start</button> + // <button onClick={e => SpeechRecognition.stopListening}>Stop</button> + // <button onClick={resetTranscript}>Reset</button> + // <p>{transcript}</p> + // </div> + // ); + // }; + // const grammar = + // '#JSGF V1.0; grammar colors; public <color> = aqua | azure | beige | bisque | black | blue | brown | chocolate | coral | crimson | cyan | fuchsia | ghostwhite | gold | goldenrod | gray | green | indigo | ivory | khaki | lavender | lime | linen | magenta | maroon | moccasin | navy | olive | orange | orchid | peru | pink | plum | purple | red | salmon | sienna | silver | snow | tan | teal | thistle | tomato | turquoise | violet | white | yellow ;'; + // const recognition = new SpeechRecognition(); + // const speechRecognitionList = new SpeechGrammarList(); + // speechRecognitionList.addFromString(grammar, 1); + // recognition.grammars = speechRecognitionList; + // recognition.continuous = false; + // recognition.lang = 'en-US'; + // recognition.interimResults = false; + // recognition.maxAlternatives = 1; + + // const diagnostic = document.querySelector('.output'); + // const bg = document.querySelector('html'); + + // document.body.onclick = () => { + // recognition.start(); + // console.log('Ready to receive a color command.'); + // }; + + // recognition.onresult = event => { + // const color = event.results[0][0].transcript; + // diagnostic!.textContent = `Result received: ${color}`; + // bg!.style.backgroundColor = color; + // }; + + //const SpeechRecognition = SpeechRecognition || webkitSpeechRecognition; + + // recognition.continous = true; + // recognition.interimResults = true; + // recognition.lang = 'en-US'; + + const queryText = this._selectionText; + + // const canvas = await html2canvas(); + // const image = canvas.toDataURL("image/png", 1.0); + // (window as any) + // .html2canvas(this._marqueeref, { + // x: 100, + // y: 100, + // width: 100, + // height: 100, + // }) + // .then((canvas: HTMLCanvasElement) => { + // const img = canvas.toDataURL('image/png'); + + // const link = document.createElement('a'); + // link.href = img; + // link.download = 'screenshot.png'; + + // document.body.appendChild(link); + // link.click(); + // link.remove(); + // }); + + // var range = window.getSelection()?.getRangeAt(0); + // var selectionContents = range?.extractContents(); + // var div = document.createElement("div"); + // div.style.color = "yellow"; + // div.appendChild(selectionContents!); + // range!.insertNode(div); + + // const canvas = document.createElement('canvas'); + // const scaling = 1 / (this._props.NativeDimScaling?.() || 1); + // const w = AnchorMenu.Instance.marqueeWidth * scaling; + // const h = AnchorMenu.Instance.marqueeHeight * scaling; + // canvas.width = w; + // canvas.height = h; + // const ctx = canvas.getContext('2d'); // draw image to canvas. scale to target dimensions + // if (ctx) { + // this._marqueeref && ctx.drawImage(div, NumCast(this._marqueeref.current?.left) * scaling, NumCast(this._marqueeref.current?.top) * scaling, w, h, 0, 0, w, h); + // } + this._loading = true; + try { + if (this._selectionText === '') { + } + const res = await gptAPICall(queryText, GPTCallType.FLASHCARD); + + console.log(res); + AnchorMenu.Instance.transferToFlashcard(res || 'Something went wrong', NumCast(this._props.layoutDoc['x']), NumCast(this._props.layoutDoc['y'])); + this._selectionText = ''; + } catch (err) { + console.error(err); + } + this._loading = false; + }; + @action finishMarquee = (/* x?: number, y?: number */) => { this._getAnchor = AnchorMenu.Instance?.GetAnchor; @@ -411,8 +571,10 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { document.removeEventListener('pointerup', this.onSelectEnd); const sel = window.getSelection(); + if (sel) { AnchorMenu.Instance.setSelectedText(sel.toString()); + AnchorMenu.Instance.setLocation(NumCast(this._props.layoutDoc['x']), NumCast(this._props.layoutDoc['y'])); } if (sel?.type === 'Range') { @@ -424,6 +586,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { GPTPopup.Instance.addDoc = this._props.sidebarAddDoc; // allows for creating collection AnchorMenu.Instance.addToCollection = this._props.DocumentView?.()._props.addDocument; + AnchorMenu.Instance.gptFlashcards = this.gptPDFFlashcards; }; @action @@ -451,6 +614,7 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { this._mainCont.current!.style.transform = ''; } this._selectionContent = selRange.cloneContents(); + this._selectionText = this._selectionContent?.textContent || ''; // clear selection @@ -612,6 +776,11 @@ export class PDFViewer extends ObservableReactComponent<IViewerProps> { /> )} </div> + {this._loading ? ( + <div className="loading-spinner" style={{ position: 'absolute' }}> + <ReactLoading type="spin" height={80} width={80} color={'blue'} /> + </div> + ) : null} </div> ); } |