From ae22fa1aa09bf74b46f4d607f0b36dbcf40c9eee Mon Sep 17 00:00:00 2001 From: Lucas Bourgeois Date: Tue, 1 Oct 2024 16:43:38 +0200 Subject: [PATCH 1/2] fix: update node version to lts 20 --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 5397c87f..3516580b 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16.18.1 +20.17.0 From e4116d520a41fa555c0a13afd3ed923d249b9ee2 Mon Sep 17 00:00:00 2001 From: Lucas Bourgeois Date: Tue, 1 Oct 2024 18:03:30 +0200 Subject: [PATCH 2/2] feat!: add support of custom emojis (slack like) --- .prettierignore | 2 +- docs/docs/api/emojisData.md | 18 ++++++-- .../documentation/Examples/emojis-data.md | 33 +++++++++++++- example/app/(examples)/basic.tsx | 8 ++-- example/app/(examples)/category-bottom.tsx | 8 ++-- example/app/(examples)/category-top.tsx | 8 ++-- example/app/(examples)/custom-buttons.tsx | 14 +++--- example/app/(examples)/dark.tsx | 8 ++-- .../app/(examples)/disabled-categories.tsx | 8 ++-- example/app/(examples)/emoji-data.tsx | 36 ++++++++++++--- example/app/(examples)/enable-recently.tsx | 8 ++-- example/app/(examples)/search.tsx | 8 ++-- example/app/(examples)/selected-emojis.tsx | 15 +++---- example/app/(examples)/static-modal.tsx | 8 ++-- example/app/(examples)/static.tsx | 8 ++-- example/app/(examples)/translated.tsx | 10 ++--- example/assets/custom/shhhh.webp | Bin 0 -> 2934 bytes example/assets/custom/silly.webp | Bin 0 -> 5684 bytes example/assets/custom/woah.webp | Bin 0 -> 3902 bytes example/src/components/Result.tsx | 31 +++++++++++++ example/src/components/Results.tsx | 27 ++++++++--- scripts/generateIcons.js | 4 ++ .../useRecentPicksPersistence.test.tsx | 25 ++++++++--- src/assets/emojis.json | 2 +- src/assets/icons/sparkles.png | Bin 0 -> 4878 bytes src/components/EmojiCategory.tsx | 4 +- src/components/Icon.tsx | 2 + src/components/SingleEmoji.tsx | 42 ++++++++++++------ src/components/SingleSkinTone.tsx | 4 +- src/contexts/KeyboardProvider.tsx | 14 +++--- src/index.tsx | 2 +- src/translation/cs.ts | 1 + src/translation/de.ts | 1 + src/translation/en.ts | 1 + src/translation/es.ts | 1 + src/translation/fr.ts | 1 + src/translation/id.ts | 1 + src/translation/it.ts | 1 + src/translation/ja.ts | 1 + src/translation/ko.ts | 1 + src/translation/no.ts | 1 + src/translation/np.ts | 1 + src/translation/pl.ts | 1 + src/translation/pt.ts | 1 + src/translation/ro.ts | 1 + src/translation/ru.ts | 1 + src/translation/se.ts | 1 + src/translation/tr.ts | 1 + src/translation/ua.ts | 1 + src/translation/vi.ts | 1 + src/types.ts | 33 +++++++++++--- src/utils/parseEmoji.ts | 25 +++++++---- src/utils/typeguards.ts | 19 ++++++++ 53 files changed, 334 insertions(+), 119 deletions(-) create mode 100644 example/assets/custom/shhhh.webp create mode 100644 example/assets/custom/silly.webp create mode 100644 example/assets/custom/woah.webp create mode 100644 example/src/components/Result.tsx create mode 100644 src/assets/icons/sparkles.png create mode 100644 src/utils/typeguards.ts diff --git a/.prettierignore b/.prettierignore index 340943ae..595a5b0d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,3 @@ # readme -README.md \ No newline at end of file +README.md diff --git a/docs/docs/api/emojisData.md b/docs/docs/api/emojisData.md index 67f491ce..3ab0e963 100644 --- a/docs/docs/api/emojisData.md +++ b/docs/docs/api/emojisData.md @@ -14,15 +14,25 @@ import { emojisByCategory } from 'rn-emoji-keyboard' Here is the EmojisData structure explained as Typescript code ```ts -type EmojiType = { - emoji: string // Visual representation of emoji + +export type EmojiTypeBase = { name: string slug: string - unicode_version: string - toneEnabled: boolean alreadySelected?: boolean } +export type UnicodeEmojiType = EmojiTypeBase & { + emoji: string // Visual representation of emoji + toneEnabled: boolean + unicode_version: string +} + +export type UriEmojiType = EmojiTypeBase & { + uri: string // Distant URI / base64 / Image.resolveAssetSource(require('asset/path/emote.ext').uri +} + +export type EmojiType = UnicodeEmojiType | UriEmojiType + type EmojisByCategory = { title: CategoryTypes data: JsonEmoji[] diff --git a/docs/docs/documentation/Examples/emojis-data.md b/docs/docs/documentation/Examples/emojis-data.md index 622df21e..98be8852 100644 --- a/docs/docs/documentation/Examples/emojis-data.md +++ b/docs/docs/documentation/Examples/emojis-data.md @@ -11,19 +11,48 @@ To preview app with this example, clone [**github repo**](https://github.com/The It's possible to pass your own set of emojis. You have to keep in mind that types and category titles must match the ones that we are using. In the example you can see custom emojis set that contains only emojis with unicode version === 11. -```jsx +Passing your set of emojis allows you to support translated keywords, names and custom emojis + +```tsx import EmojiPicker, { emojisByCategory } from 'rn-emoji-keyboard' +import { isUnicodeEmoji } from '../../../src/utils/parseEmoji' import type { EmojisByCategory } from 'src/types' +import { Image } from 'react-native' const getCustomEmojis = () => { const newEmojiSet: EmojisByCategory[] = [] + + // Filter in categories, emojis version equal to unicode 11 for (const [, value] of Object.entries(emojisByCategory)) { - const newData = value.data.filter((emoji) => parseFloat(emoji.v) === 11) + const newData = value.data.filter( + (emoji) => isUnicodeEmoji(emoji) && parseFloat(emoji.v) === 11, + ) newEmojiSet.push({ title: value.title, data: newData, }) } + + // Add in custom category URI sourced emojis + // Can be either a distant https:// or a base64 formatted image or a resolved image asset + const customCategoryIndex = emojisByCategory.findIndex(({ title }) => title === 'custom') + newEmojiSet[customCategoryIndex]!.data = [ + { + uri: Image.resolveAssetSource(require('example/assets/custom/shhhh.webp')).uri, + keywords: ['shhhh', 'face'], + name: 'shhhh', + }, + { + uri: Image.resolveAssetSource(require('example/assets/custom/silly.webp')).uri, + keywords: ['silly', 'face'], + name: 'silly', + }, + { + uri: Image.resolveAssetSource(require('example/assets/custom/woah.webp')).uri, + keywords: ['woaah', 'face'], + name: 'woaah', + }, + ] return newEmojiSet } diff --git a/example/app/(examples)/basic.tsx b/example/app/(examples)/basic.tsx index e34807e4..21046135 100644 --- a/example/app/(examples)/basic.tsx +++ b/example/app/(examples)/basic.tsx @@ -1,20 +1,20 @@ import { Button } from 'example/src/components/Button' -import { Results } from 'example/src/components/Results' import React from 'react' import EmojiPicker, { type EmojiType } from 'rn-emoji-keyboard' +import { Result } from 'example/src/components/Result' export default function () { - const [result, setResult] = React.useState() + const [result, setResult] = React.useState() const [isModalOpen, setIsModalOpen] = React.useState(false) const handlePick = (emoji: EmojiType) => { console.log(emoji) - setResult(emoji.emoji) + setResult(emoji) setIsModalOpen((prev) => !prev) } return ( <> - + {result && }