@ -10,6 +10,11 @@ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import IconButton from 'flavours/glitch/components/icon_button' ;
import Button from 'flavours/glitch/components/button' ;
import Video from 'flavours/glitch/features/video' ;
import { TesseractWorker } from 'tesseract.js' ;
import Textarea from 'react-textarea-autosize' ;
import UploadProgress from 'flavours/glitch/features/compose/components/upload_progress' ;
import CharacterCounter from 'flavours/glitch/features/compose/components/character_counter' ;
import { length } from 'stringz' ;
const messages = defineMessages ( {
close : { id : 'lightbox.close' , defaultMessage : 'Close' } ,
@ -29,6 +34,12 @@ const mapDispatchToProps = (dispatch, { id }) => ({
} ) ;
const removeExtraLineBreaks = str => str . replace ( /\n\n/g , '******' )
. replace ( /\n/g , ' ' )
. replace ( /\*\*\*\*\*\*/g , '\n\n' ) ;
const assetHost = process . env . CDN _HOST || '' ;
export default @ connect ( mapStateToProps , mapDispatchToProps )
@ injectIntl
class FocalPointModal extends ImmutablePureComponent {
@ -47,6 +58,7 @@ class FocalPointModal extends ImmutablePureComponent {
dragging : false ,
description : '' ,
dirty : false ,
progress : 0 ,
} ;
componentWillMount ( ) {
@ -133,9 +145,27 @@ class FocalPointModal extends ImmutablePureComponent {
this . node = c ;
}
handleTextDetection = ( ) => {
const { media } = this . props ;
const worker = new TesseractWorker ( {
workerPath : ` ${ assetHost } /packs/ocr/worker.min.js ` ,
corePath : ` ${ assetHost } /packs/ocr/tesseract-core.wasm.js ` ,
langPath : ` ${ assetHost } /ocr/lang-data ` ,
} ) ;
this . setState ( { detecting : true } ) ;
worker . recognize ( media . get ( 'url' ) )
. progress ( ( { progress } ) => this . setState ( { progress } ) )
. finally ( ( ) => worker . terminate ( ) )
. then ( ( { text } ) => this . setState ( { description : removeExtraLineBreaks ( text ) , dirty : true , detecting : false } ) )
. catch ( ( ) => this . setState ( { detecting : false } ) ) ;
}
render ( ) {
const { media , intl , onClose } = this . props ;
const { x , y , dragging , description , dirty } = this . state ;
const { x , y , dragging , description , dirty , detecting , progress } = this . state ;
const width = media . getIn ( [ 'meta' , 'original' , 'width' ] ) || null ;
const height = media . getIn ( [ 'meta' , 'original' , 'height' ] ) || null ;
@ -158,15 +188,27 @@ class FocalPointModal extends ImmutablePureComponent {
< label className = 'setting-text-label' htmlFor = 'upload-modal__description' > < FormattedMessage id = 'upload_form.description' defaultMessage = 'Describe for the visually impaired' / > < / l a b e l >
< textarea
id = 'upload-modal__description'
className = 'setting-text light'
value = { description }
onChange = { this . handleChange }
autoFocus
/ >
< div className = 'setting-text__wrapper' >
< Textarea
id = 'upload-modal__description'
className = 'setting-text light'
value = { detecting ? '…' : description }
onChange = { this . handleChange }
disabled = { detecting }
autoFocus
/ >
< div className = 'setting-text__modifiers' >
< UploadProgress progress = { progress * 100 } active = { detecting } icon = 'file-text-o' message = { < FormattedMessage id = 'upload_modal.analyzing_picture' defaultMessage = 'Analyzing picture…' / > } / >
< / d i v >
< / d i v >
< div className = 'setting-text__toolbar' >
< button disabled = { detecting || media . get ( 'type' ) !== 'image' } className = 'link-button' onClick = { this . handleTextDetection } > < FormattedMessage id = 'upload_modal.detect_text' defaultMessage = 'Detect text from picture' / > < / b u t t o n >
< CharacterCounter max = { 420 } text = { detecting ? '' : description } / >
< / d i v >
< Button disabled = { ! dirty } text = { intl . formatMessage ( messages . apply ) } onClick = { this . handleSubmit } / >
< Button disabled = { ! dirty || detecting || length ( description ) > 420 } text = { intl . formatMessage ( messages . apply ) } onClick = { this . handleSubmit } / >
< / d i v >
< div className = 'report-modal__statuses' >