@ -1,11 +1,7 @@
import PropTypes from 'prop-types' ;
import PropTypes from 'prop-types' ;
import { PureComponent } from 'react' ;
import { PureComponent } from 'react' ;
import {
import { defineMessages , injectIntl , FormattedMessage , FormattedList } from 'react-intl' ;
injectIntl ,
FormattedMessage ,
defineMessages ,
} from 'react-intl' ;
import classNames from 'classnames' ;
import classNames from 'classnames' ;
@ -52,6 +48,16 @@ class Search extends PureComponent {
options : [ ] ,
options : [ ] ,
} ;
} ;
defaultOptions = [
{ label : < > < mark > has : < / mark > < FormattedList type = 'disjunction' value = { [ 'media' , 'poll' , 'embed' ] } / > < / > , action : e => { e . preventDefault ( ) ; this . _insertText ( 'has:' ) } } ,
{ label : < > < mark > is : < / mark > < FormattedList type = 'disjunction' value = { [ 'reply' , 'sensitive' ] } / > < / > , action : e => { e . preventDefault ( ) ; this . _insertText ( 'is:' ) } } ,
{ label : < > < mark > language : < / mark > < FormattedMessage id = 'search_popout.language_code' defaultMessage = 'ISO language code' / > < / > , action : e => { e . preventDefault ( ) ; this . _insertText ( 'language:' ) } } ,
{ label : < > < mark > from : < / mark > < FormattedMessage id = 'search_popout.user' defaultMessage = 'user' / > < / > , action : e => { e . preventDefault ( ) ; this . _insertText ( 'from:' ) } } ,
{ label : < > < mark > before : < / mark > < FormattedMessage id = 'search_popout.specific_date' defaultMessage = 'specific date' / > < / > , action : e => { e . preventDefault ( ) ; this . _insertText ( 'before:' ) } } ,
{ label : < > < mark > during : < / mark > < FormattedMessage id = 'search_popout.specific_date' defaultMessage = 'specific date' / > < / > , action : e => { e . preventDefault ( ) ; this . _insertText ( 'during:' ) } } ,
{ label : < > < mark > after : < / mark > < FormattedMessage id = 'search_popout.specific_date' defaultMessage = 'specific date' / > < / > , action : e => { e . preventDefault ( ) ; this . _insertText ( 'after:' ) } } ,
] ;
setRef = c => {
setRef = c => {
this . searchForm = c ;
this . searchForm = c ;
} ;
} ;
@ -100,7 +106,7 @@ class Search extends PureComponent {
handleKeyDown = ( e ) => {
handleKeyDown = ( e ) => {
const { selectedOption } = this . state ;
const { selectedOption } = this . state ;
const options = this . _getOptions ( ) ;
const options = this . _getOptions ( ) .concat ( this . defaultOptions ) ;
switch ( e . key ) {
switch ( e . key ) {
case 'Escape' :
case 'Escape' :
@ -131,10 +137,9 @@ class Search extends PureComponent {
if ( selectedOption === - 1 ) {
if ( selectedOption === - 1 ) {
this . _submit ( ) ;
this . _submit ( ) ;
} else if ( options . length > 0 ) {
} else if ( options . length > 0 ) {
options [ selectedOption ] . action ( ) ;
options [ selectedOption ] . action ( e ) ;
}
}
this . _unfocus ( ) ;
break ;
break ;
case 'Delete' :
case 'Delete' :
if ( selectedOption > - 1 && options . length > 0 ) {
if ( selectedOption > - 1 && options . length > 0 ) {
@ -161,6 +166,7 @@ class Search extends PureComponent {
router . history . push ( ` /tags/ ${ query } ` ) ;
router . history . push ( ` /tags/ ${ query } ` ) ;
onClickSearchResult ( query , 'hashtag' ) ;
onClickSearchResult ( query , 'hashtag' ) ;
this . _unfocus ( ) ;
} ;
} ;
handleAccountClick = ( ) => {
handleAccountClick = ( ) => {
@ -171,6 +177,7 @@ class Search extends PureComponent {
router . history . push ( ` /@ ${ query } ` ) ;
router . history . push ( ` /@ ${ query } ` ) ;
onClickSearchResult ( query , 'account' ) ;
onClickSearchResult ( query , 'account' ) ;
this . _unfocus ( ) ;
} ;
} ;
handleURLClick = ( ) => {
handleURLClick = ( ) => {
@ -178,6 +185,7 @@ class Search extends PureComponent {
const { onOpenURL } = this . props ;
const { onOpenURL } = this . props ;
onOpenURL ( router . history ) ;
onOpenURL ( router . history ) ;
this . _unfocus ( ) ;
} ;
} ;
handleStatusSearch = ( ) => {
handleStatusSearch = ( ) => {
@ -196,6 +204,8 @@ class Search extends PureComponent {
} else if ( search . get ( 'type' ) === 'hashtag' ) {
} else if ( search . get ( 'type' ) === 'hashtag' ) {
router . history . push ( ` /tags/ ${ search . get ( 'q' ) } ` ) ;
router . history . push ( ` /tags/ ${ search . get ( 'q' ) } ` ) ;
}
}
this . _unfocus ( ) ;
} ;
} ;
handleForgetRecentSearchClick = search => {
handleForgetRecentSearchClick = search => {
@ -208,6 +218,18 @@ class Search extends PureComponent {
document . querySelector ( '.ui' ) . parentElement . focus ( ) ;
document . querySelector ( '.ui' ) . parentElement . focus ( ) ;
}
}
_insertText ( text ) {
const { value , onChange } = this . props ;
if ( value === '' ) {
onChange ( text ) ;
} else if ( value [ value . length - 1 ] === ' ' ) {
onChange ( ` ${ value } ${ text } ` ) ;
} else {
onChange ( ` ${ value } ${ text } ` ) ;
}
}
_submit ( type ) {
_submit ( type ) {
const { onSubmit , openInRoute } = this . props ;
const { onSubmit , openInRoute } = this . props ;
const { router } = this . context ;
const { router } = this . context ;
@ -217,6 +239,8 @@ class Search extends PureComponent {
if ( openInRoute ) {
if ( openInRoute ) {
router . history . push ( '/search' ) ;
router . history . push ( '/search' ) ;
}
}
this . _unfocus ( ) ;
}
}
_getOptions ( ) {
_getOptions ( ) {
@ -337,6 +361,16 @@ class Search extends PureComponent {
< / div >
< / div >
< / >
< / >
) }
) }
< h4 > < FormattedMessage id = 'search_popout.options' defaultMessage = 'Search options' / > < / h4 >
< div className = 'search__popout__menu' >
{ this . defaultOptions . map ( ( { key , label , action } , i ) => (
< button key = { key } onMouseDown = { action } className = { classNames ( 'search__popout__menu__item' , { selected : selectedOption === ( options . length + i ) } ) } >
{ label }
< / button >
) ) }
< / div >
< / div >
< / div >
< / div >
< / div >
) ;
) ;