Refactor search

exclude-unsupported-native-emojis
Etienne Lemay 2016-07-08 13:56:29 -04:00
parent 49ec3b9efe
commit 47f2341f53
3 changed files with 73 additions and 31 deletions

View File

@ -7,8 +7,13 @@ export default class Anchors extends React.Component {
constructor(props) { constructor(props) {
super(props) super(props)
var defaultCategory = props.categories[0]
if (defaultCategory.anchor) {
defaultCategory = defaultCategory.anchor
}
this.state = { this.state = {
selected: props.categories[0].name selected: defaultCategory.name
} }
} }
@ -18,7 +23,11 @@ export default class Anchors extends React.Component {
return <div className='emoji-picker-anchors'> return <div className='emoji-picker-anchors'>
{categories.map((category, i) => { {categories.map((category, i) => {
var { name } = category var { name, anchor } = category
if (anchor) {
return null
}
return ( return (
<span <span

View File

@ -28,8 +28,26 @@ export default class Category extends React.Component {
this.memoizeSize() this.memoizeSize()
} }
componentDidUpdate() { shouldComponentUpdate(nextProps, nextState) {
this.memoizeSize() var { name, perLine, emojis, emojiProps } = this.props,
{ skin, size, sheetURL } = emojiProps,
{ perLine: nextPerLine, emojis: nextEmojis, emojiProps: nextEmojiProps } = nextProps,
{ skin: nextSkin, size: nextSize, sheetURL: nextSheetURL } = nextEmojiProps,
shouldUpdate = false
if (name == 'Recent' && perLine != nextPerLine) {
shouldUpdate = true
}
if (name == 'Search') {
shouldUpdate = !(emojis == nextEmojis)
}
if (skin != nextSkin || size != nextSize || sheetURL != nextSheetURL) {
shouldUpdate = true
}
return shouldUpdate
} }
memoizeSize() { memoizeSize() {
@ -81,6 +99,7 @@ export default class Category extends React.Component {
containerStyles = { containerStyles = {
height: 1, height: 1,
overflow: 'hidden', overflow: 'hidden',
marginBottom: '-1px',
} }
} }

View File

@ -1,13 +1,18 @@
import '../vendor/raf-polyfill' import '../vendor/raf-polyfill'
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom'
import data from '../../data' import data from '../../data'
import {store, frequently} from '../utils' import {store, frequently} from '../utils'
import {Anchors, Category, Preview, Search} from '.' import {Anchors, Category, Preview, Search} from '.'
const DEFAULT_CATEGORIES = [ const RECENT_CATEGORY = { name: 'Recent', emojis: null }
{ name: 'Recent', emojis: null } const SEARCH_CATEGORY = { name: 'Search', emojis: null, anchor: RECENT_CATEGORY }
const CATEGORIES = [
SEARCH_CATEGORY,
RECENT_CATEGORY,
].concat(data.categories) ].concat(data.categories)
export default class Picker extends React.Component { export default class Picker extends React.Component {
@ -16,7 +21,6 @@ export default class Picker extends React.Component {
this.testStickyPosition() this.testStickyPosition()
this.state = { this.state = {
categories: DEFAULT_CATEGORIES,
skin: store.get('skin') || props.skin, skin: store.get('skin') || props.skin,
} }
} }
@ -28,6 +32,7 @@ export default class Picker extends React.Component {
} }
componentDidUpdate() { componentDidUpdate() {
this.updateCategoriesSize()
this.handleScroll() this.handleScroll()
} }
@ -57,20 +62,16 @@ export default class Picker extends React.Component {
this.props.onClick(emoji) this.props.onClick(emoji)
frequently.add(emoji) frequently.add(emoji)
var component = this.refs['category-0'] var component = this.refs['category-1']
if (component && component.props.name == 'Recent') { if (component) {
let maxMargin = component.maxMargin let maxMargin = component.maxMargin
component.forceUpdate() component.forceUpdate()
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
component.memoizeSize()
if (maxMargin == component.maxMargin) return if (maxMargin == component.maxMargin) return
var { categories } = this.state
for (let i = 0, l = categories.length; i < l; i++) {
let component = this.refs[`category-${i}`]
if (component) component.memoizeSize()
}
this.updateCategoriesSize()
this.handleScrollPaint() this.handleScrollPaint()
}) })
} }
@ -88,18 +89,18 @@ export default class Picker extends React.Component {
var target = this.refs.scroll, var target = this.refs.scroll,
scrollTop = target.scrollTop, scrollTop = target.scrollTop,
scrollingDown = scrollTop >= (this.scrollTop || 0), scrollingDown = scrollTop > (this.scrollTop || 0),
activeCategory = null, activeCategory = null
{ categories } = this.state
for (let i = 0, l = categories.length; i < l; i++) { for (let i = 0, l = CATEGORIES.length; i < l; i++) {
let ii = scrollingDown ? (categories.length - 1 - i) : i, let ii = scrollingDown ? (CATEGORIES.length - 1 - i) : i,
category = categories[ii], category = CATEGORIES[ii],
component = this.refs[`category-${ii}`] component = this.refs[`category-${ii}`]
if (component) { if (component) {
let active = component.handleScroll(scrollTop) let active = component.handleScroll(scrollTop)
if (active && !activeCategory) { if (active && !activeCategory) {
if (category.anchor) category = category.anchor
activeCategory = category activeCategory = category
} }
} }
@ -118,14 +119,20 @@ export default class Picker extends React.Component {
} }
handleSearch(emojis) { handleSearch(emojis) {
if (emojis == null) { SEARCH_CATEGORY.emojis = emojis
this.setState({ categories: DEFAULT_CATEGORIES })
} else { for (let i = 0, l = CATEGORIES.length; i < l; i++) {
this.setState({ categories: [{ let component = this.refs[`category-${i}`]
name: 'Search',
emojis: emojis, if (component && component.props.name != 'Search') {
}]}) let DOMNode = ReactDOM.findDOMNode(component),
display = emojis ? 'none' : null
if (DOMNode) DOMNode.style.display = display
}
} }
this.forceUpdate()
} }
handleAnchorClick(category, i) { handleAnchorClick(category, i) {
@ -135,7 +142,7 @@ export default class Picker extends React.Component {
if (component) { if (component) {
let { top } = component let { top } = component
if (i == 0) { if (category.name == 'Recent') {
top = 0 top = 0
} else { } else {
top += 1 top += 1
@ -152,6 +159,13 @@ export default class Picker extends React.Component {
store.update(newState) store.update(newState)
} }
updateCategoriesSize() {
for (let i = 0, l = CATEGORIES.length; i < l; i++) {
let component = this.refs[`category-${i}`]
if (component) component.memoizeSize()
}
}
render() { render() {
var { perLine, emojiSize, sheetURL } = this.props, var { perLine, emojiSize, sheetURL } = this.props,
{ skin } = this.state, { skin } = this.state,
@ -161,7 +175,7 @@ export default class Picker extends React.Component {
<div className='emoji-picker-bar'> <div className='emoji-picker-bar'>
<Anchors <Anchors
ref='anchors' ref='anchors'
categories={DEFAULT_CATEGORIES} categories={CATEGORIES}
onAnchorClick={this.handleAnchorClick.bind(this)} onAnchorClick={this.handleAnchorClick.bind(this)}
/> />
</div> </div>
@ -171,7 +185,7 @@ export default class Picker extends React.Component {
onSearch={this.handleSearch.bind(this)} onSearch={this.handleSearch.bind(this)}
/> />
{this.state.categories.map((category, i) => { {CATEGORIES.map((category, i) => {
return <Category return <Category
ref={`category-${i}`} ref={`category-${i}`}
key={category.name} key={category.name}