android doesn't support all emojis. use different lib that tells us which emojis are supported.
This commit is contained in:
parent
ac6f870028
commit
3b1d561a66
89
index.js
89
index.js
|
@ -10,34 +10,78 @@ import {
|
|||
TouchableOpacity,
|
||||
TouchableWithoutFeedback,
|
||||
View,
|
||||
Platform,
|
||||
} from 'react-native'
|
||||
|
||||
import emoji from 'emojilib'
|
||||
import emoji from 'emoji-datasource'
|
||||
|
||||
import {
|
||||
groupBy,
|
||||
orderBy,
|
||||
includes,
|
||||
} from 'lodash/collection'
|
||||
|
||||
import {
|
||||
mapValues,
|
||||
} from 'lodash/object'
|
||||
|
||||
//polyfil for android
|
||||
require('string.fromcodepoint');
|
||||
|
||||
// i dont understand ANY of this but there's somethign called codepoints and surrogate pairs
|
||||
// and this converts utf16 to a charachter in javascript. see more here:
|
||||
//https://mathiasbynens.be/notes/javascript-unicode
|
||||
//https://mathiasbynens.be/notes/javascript-escapes#unicode-code-point
|
||||
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint
|
||||
const charFromUtf16 = utf16 => String.fromCodePoint(...utf16.split('-').map(u => '0x' + u))
|
||||
const charFromEmojiObj = obj => charFromUtf16(obj.unified)
|
||||
const blacklistedEmojis = ['white_frowning_face', 'keycap_star', 'eject']
|
||||
|
||||
|
||||
const isAndroid = Platform.OS == 'android'
|
||||
const letterSpacing = 10
|
||||
const defaultEmojiSize = 30
|
||||
const categories = ['People', 'Nature', 'Foods', 'Activity', 'Places', 'Objects', 'Symbols', 'Flags']
|
||||
const filteredEmojis = emoji.filter(e => isAndroid ? !!e.google : !includes(blacklistedEmojis, e.short_name))
|
||||
// sort emojis by 'sort_order' then group them into categories
|
||||
const groupedAndSorted = groupBy(orderBy(filteredEmojis, 'sort_order'), 'category')
|
||||
// convert the emoji object to a character
|
||||
const emojisByCategory = mapValues(groupedAndSorted, group => group.map(charFromEmojiObj))
|
||||
|
||||
|
||||
const EmojiPicker = (props) => {
|
||||
let container = []
|
||||
let rowCount = props.rows || 7
|
||||
let ordered = emoji.ordered
|
||||
for (var i = 0; i < rowCount; i++) {
|
||||
let row = []
|
||||
for (var n = 0; n < ordered.length/rowCount; n++) {
|
||||
let index = i + n * rowCount + 1
|
||||
if (index < ordered.length) {
|
||||
row.push(ordered[index])
|
||||
|
||||
// instead listing emojis left-to-right we want to list them top-to-bottom.
|
||||
// we split them in to rows by sequentially taking every Xth value, where X is the number of rows
|
||||
function transposeEmojisVertically(emojis, rowCount = 7) {
|
||||
let array = []
|
||||
for (var i = 0; i < rowCount; i++) {
|
||||
let row = []
|
||||
for (var n = 0; n < emojis.length/rowCount; n++) {
|
||||
let index = i + n * rowCount
|
||||
if (index < emojis.length) {
|
||||
row.push(emojis[index])
|
||||
}
|
||||
}
|
||||
array.push(row)
|
||||
}
|
||||
container.push(row)
|
||||
return array
|
||||
}
|
||||
|
||||
function renderSectionForCategory(c) {
|
||||
let emojis = transposeEmojisVertically(emojisByCategory[c])
|
||||
return (
|
||||
<View key={c} style={styles.innerContainer}>
|
||||
<Text style={[styles.headerText, props.headerStyle]}>{c}</Text>
|
||||
{emojis.map(array => <Row {...props} array={array} key={array[0]} />)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={props.style}>
|
||||
<ScrollView horizontal={true}>
|
||||
<View style={styles.innerContainer}>
|
||||
{container.map(array => <Row {...props} array={array} key={array[0]} />)}
|
||||
</View>
|
||||
{categories.map(renderSectionForCategory)}
|
||||
</ScrollView>
|
||||
{props.hideClearButton ? null : <ClearButon {...props} />}
|
||||
</View>
|
||||
|
@ -49,25 +93,28 @@ const Row = props => {
|
|||
|
||||
function handlePress(event) {
|
||||
let i = Math.floor(event.nativeEvent.locationX/(size + 5 + letterSpacing/2))
|
||||
let name = props.array[i]
|
||||
props.onEmojiSelected(emoji.lib[name].char)
|
||||
if (i < props.array.length) {
|
||||
let emoji = props.array[i]
|
||||
props.onEmojiSelected(emoji)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<TouchableWithoutFeedback onPress={handlePress}>
|
||||
<View>
|
||||
<Text style={[styles.rowText, {fontSize: size}]} >
|
||||
{props.array.map(name => emoji.lib[name].char)}
|
||||
{props.array}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableWithoutFeedback>
|
||||
)
|
||||
}
|
||||
|
||||
const ClearButon = props => {
|
||||
return (
|
||||
<TouchableOpacity
|
||||
onPress={() => props.onEmojiSelected(null)}>
|
||||
<Text style={styles.clearButton}>
|
||||
<Text style={[styles.clearButton, props.clearButtonStyle]}>
|
||||
{props.clearButtonText || 'Clear'}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
@ -87,6 +134,7 @@ let styles = StyleSheet.create({
|
|||
clearButton: {
|
||||
padding: 15,
|
||||
textAlign: 'center',
|
||||
color: 'black',
|
||||
},
|
||||
absolute: {
|
||||
position: 'absolute',
|
||||
|
@ -116,6 +164,11 @@ let styles = StyleSheet.create({
|
|||
rowText: {
|
||||
letterSpacing: letterSpacing,
|
||||
paddingHorizontal: 5,
|
||||
color: 'black',
|
||||
},
|
||||
headerText: {
|
||||
padding: 5,
|
||||
color: 'black',
|
||||
}
|
||||
})
|
||||
|
||||
|
|
13
package.json
13
package.json
|
@ -1,11 +1,8 @@
|
|||
{
|
||||
"name": "react-native-emoji-picker",
|
||||
"version": "0.1.2",
|
||||
"version": "0.2.0",
|
||||
"description": "Simple emoji picker for react-native",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:yonahforst/react-native-emoji-picker.git"
|
||||
|
@ -18,11 +15,13 @@
|
|||
"emoji-picker"
|
||||
],
|
||||
"devDependencies": {
|
||||
"react": "^0.14.8",
|
||||
"react-native": "^0.25.0"
|
||||
"react": "^15.2.0",
|
||||
"react-native": "^0.30.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"emojilib": "^2.0.2"
|
||||
"emoji-datasource": "^2.4.4",
|
||||
"lodash": "^4.11.1",
|
||||
"string.fromcodepoint": "^0.2.1"
|
||||
},
|
||||
"author": "Yonah Forst <yonaforst@hotmail.com> (https://github.com/yonahforst)",
|
||||
"license": "MIT",
|
||||
|
|
Loading…
Reference in New Issue