add twemoji
This commit is contained in:
@@ -253,6 +253,14 @@
|
|||||||
from { opacity: 1; }
|
from { opacity: 1; }
|
||||||
to { opacity: 0; }
|
to { opacity: 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Twemoji */
|
||||||
|
img.twemoji {
|
||||||
|
height: 1em;
|
||||||
|
width: 1em;
|
||||||
|
margin: 0 .05em 0 .1em;
|
||||||
|
vertical-align: -0.1em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</style>
|
</style>
|
||||||
{% include "scripts.html" %}
|
{% include "scripts.html" %}
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
"@bam.tech/react-native-image-resizer": "^3.0.4",
|
"@bam.tech/react-native-image-resizer": "^3.0.4",
|
||||||
"@braintree/sanitize-url": "^6.0.2",
|
"@braintree/sanitize-url": "^6.0.2",
|
||||||
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
"@discord/bottom-sheet": "bluesky-social/react-native-bottom-sheet",
|
||||||
|
"@discordapp/twemoji": "^15.0.3",
|
||||||
"@emoji-mart/react": "^1.1.1",
|
"@emoji-mart/react": "^1.1.1",
|
||||||
"@expo/html-elements": "^0.4.2",
|
"@expo/html-elements": "^0.4.2",
|
||||||
"@expo/webpack-config": "^19.0.0",
|
"@expo/webpack-config": "^19.0.0",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {InlineLinkText, LinkProps} from '#/components/Link'
|
|||||||
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
import {ProfileHoverCard} from '#/components/ProfileHoverCard'
|
||||||
import {TagMenu, useTagMenuControl} from '#/components/TagMenu'
|
import {TagMenu, useTagMenuControl} from '#/components/TagMenu'
|
||||||
import {Text, TextProps} from '#/components/Typography'
|
import {Text, TextProps} from '#/components/Typography'
|
||||||
|
import {Twemoji} from './Twemoji'
|
||||||
|
|
||||||
const WORD_WRAP = {wordWrap: 1}
|
const WORD_WRAP = {wordWrap: 1}
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ export function RichText({
|
|||||||
style={[plainStyles, {fontSize}]}
|
style={[plainStyles, {fontSize}]}
|
||||||
// @ts-ignore web only -prf
|
// @ts-ignore web only -prf
|
||||||
dataSet={WORD_WRAP}>
|
dataSet={WORD_WRAP}>
|
||||||
{text}
|
<Twemoji>{text}</Twemoji>
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -83,7 +84,7 @@ export function RichText({
|
|||||||
numberOfLines={numberOfLines}
|
numberOfLines={numberOfLines}
|
||||||
// @ts-ignore web only -prf
|
// @ts-ignore web only -prf
|
||||||
dataSet={WORD_WRAP}>
|
dataSet={WORD_WRAP}>
|
||||||
{text}
|
<Twemoji>{text}</Twemoji>
|
||||||
</Text>
|
</Text>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -109,7 +110,7 @@ export function RichText({
|
|||||||
// @ts-ignore TODO
|
// @ts-ignore TODO
|
||||||
dataSet={WORD_WRAP}
|
dataSet={WORD_WRAP}
|
||||||
onPress={onLinkPress}>
|
onPress={onLinkPress}>
|
||||||
{segment.text}
|
<Twemoji>{segment.text}</Twemoji>
|
||||||
</InlineLinkText>
|
</InlineLinkText>
|
||||||
</ProfileHoverCard>,
|
</ProfileHoverCard>,
|
||||||
)
|
)
|
||||||
@@ -127,7 +128,7 @@ export function RichText({
|
|||||||
dataSet={WORD_WRAP}
|
dataSet={WORD_WRAP}
|
||||||
shareOnLongPress
|
shareOnLongPress
|
||||||
onPress={onLinkPress}>
|
onPress={onLinkPress}>
|
||||||
{toShortUrl(segment.text)}
|
<Twemoji>{toShortUrl(segment.text)}</Twemoji>
|
||||||
</InlineLinkText>,
|
</InlineLinkText>,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -148,7 +149,7 @@ export function RichText({
|
|||||||
/>,
|
/>,
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
els.push(segment.text)
|
els.push(<Twemoji key={key}>{segment.text}</Twemoji>)
|
||||||
}
|
}
|
||||||
key++
|
key++
|
||||||
}
|
}
|
||||||
@@ -242,7 +243,7 @@ function RichTextTag({
|
|||||||
},
|
},
|
||||||
style,
|
style,
|
||||||
]}>
|
]}>
|
||||||
{text}
|
<Twemoji>{text}</Twemoji>
|
||||||
</Text>
|
</Text>
|
||||||
</TagMenu>
|
</TagMenu>
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
let Twemoji = ({children}: {children: string}): React.ReactNode => children
|
||||||
|
|
||||||
|
Twemoji = React.memo(Twemoji)
|
||||||
|
export {Twemoji}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import twemoji from '@discordapp/twemoji'
|
||||||
|
import Graphemer from 'graphemer'
|
||||||
|
|
||||||
|
// Thanks to https://gist.github.com/chibicode/fe195d792270910226c928b69a468206?permalink_comment_id=4241184#gistcomment-4241184
|
||||||
|
// for figuring this out
|
||||||
|
const U200D = String.fromCharCode(0x200d)
|
||||||
|
const UFE0Fg = /\uFE0F/g
|
||||||
|
|
||||||
|
let Twemoji = ({children}: {children: string}): React.ReactNode => {
|
||||||
|
if (!/\p{Extended_Pictographic}/u.test(children)) {
|
||||||
|
return children
|
||||||
|
}
|
||||||
|
|
||||||
|
const splitter = new Graphemer()
|
||||||
|
const graphemes = splitter.iterateGraphemes(children)
|
||||||
|
let result: React.ReactNode[] = []
|
||||||
|
let i = 0
|
||||||
|
for (const grapheme of graphemes) {
|
||||||
|
if (/\p{Extended_Pictographic}/u.test(grapheme)) {
|
||||||
|
const HexCodePoint = twemoji.convert.toCodePoint(
|
||||||
|
grapheme.indexOf(U200D) < 0 ? grapheme.replace(UFE0Fg, '') : grapheme,
|
||||||
|
)
|
||||||
|
result.push(
|
||||||
|
<img
|
||||||
|
key={i++}
|
||||||
|
src={`https://cdn.jsdelivr.net/gh/jdecked/twemoji@latest/assets/72x72/${HexCodePoint}.png`}
|
||||||
|
alt={grapheme}
|
||||||
|
className="twemoji"
|
||||||
|
/>,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
result.push(grapheme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
Twemoji = React.memo(Twemoji)
|
||||||
|
export {Twemoji}
|
||||||
@@ -257,6 +257,14 @@
|
|||||||
from { opacity: 1; }
|
from { opacity: 1; }
|
||||||
to { opacity: 0; }
|
to { opacity: 0; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Twemoji */
|
||||||
|
img.twemoji {
|
||||||
|
height: 1em;
|
||||||
|
width: 1em;
|
||||||
|
margin: 0 .05em 0 .1em;
|
||||||
|
vertical-align: -0.1em;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|||||||
@@ -3119,6 +3119,16 @@
|
|||||||
"@gorhom/portal" "1.0.14"
|
"@gorhom/portal" "1.0.14"
|
||||||
invariant "^2.2.4"
|
invariant "^2.2.4"
|
||||||
|
|
||||||
|
"@discordapp/twemoji@^15.0.3":
|
||||||
|
version "15.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/@discordapp/twemoji/-/twemoji-15.0.3.tgz#71a428080c21df5c305121bc1f0fc42cf3a3cfcc"
|
||||||
|
integrity sha512-5t0LLrNaSqViG0cSaomWwfR0+3fWqok+xLq40M8hJHxNX7s8gIoyNZYybQJo+s5/rGMjgdldpt8Ox8MapGvBUA==
|
||||||
|
dependencies:
|
||||||
|
"@twemoji/parser" "15.0.0"
|
||||||
|
fs-extra "^8.0.1"
|
||||||
|
jsonfile "^5.0.0"
|
||||||
|
universalify "^0.1.2"
|
||||||
|
|
||||||
"@discoveryjs/json-ext@0.5.7", "@discoveryjs/json-ext@^0.5.0":
|
"@discoveryjs/json-ext@0.5.7", "@discoveryjs/json-ext@^0.5.0":
|
||||||
version "0.5.7"
|
version "0.5.7"
|
||||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||||
@@ -7743,6 +7753,11 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@tsconfig/react-native/-/react-native-2.0.3.tgz#79ad8efc6d3729152da6cb23725b6c364a7349b2"
|
resolved "https://registry.yarnpkg.com/@tsconfig/react-native/-/react-native-2.0.3.tgz#79ad8efc6d3729152da6cb23725b6c364a7349b2"
|
||||||
integrity sha512-jE58snEKBd9DXfyR4+ssZmYJ/W2mOSnNrvljR0aLyQJL9JKX6vlWELHkRjb3HBbcM9Uy0hZGijXbqEAjOERW2A==
|
integrity sha512-jE58snEKBd9DXfyR4+ssZmYJ/W2mOSnNrvljR0aLyQJL9JKX6vlWELHkRjb3HBbcM9Uy0hZGijXbqEAjOERW2A==
|
||||||
|
|
||||||
|
"@twemoji/parser@15.0.0":
|
||||||
|
version "15.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@twemoji/parser/-/parser-15.0.0.tgz#8ae9749659ef524b5f0e6ee1412d0e48865e77bf"
|
||||||
|
integrity sha512-lh9515BNsvKSNvyUqbj5yFu83iIDQ77SwVcsN/SnEGawczhsKU6qWuogewN1GweTi5Imo5ToQ9s+nNTf97IXvg==
|
||||||
|
|
||||||
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
|
"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14":
|
||||||
version "7.20.1"
|
version "7.20.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b"
|
resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.1.tgz#916ecea274b0c776fec721e333e55762d3a9614b"
|
||||||
@@ -12856,7 +12871,7 @@ fs-extra@^10.0.0:
|
|||||||
jsonfile "^6.0.1"
|
jsonfile "^6.0.1"
|
||||||
universalify "^2.0.0"
|
universalify "^2.0.0"
|
||||||
|
|
||||||
fs-extra@^8.1.0, fs-extra@~8.1.0:
|
fs-extra@^8.0.1, fs-extra@^8.1.0, fs-extra@~8.1.0:
|
||||||
version "8.1.0"
|
version "8.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
|
||||||
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==
|
||||||
@@ -15564,6 +15579,15 @@ jsonfile@^4.0.0:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
graceful-fs "^4.1.6"
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
|
jsonfile@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-5.0.0.tgz#e6b718f73da420d612823996fdf14a03f6ff6922"
|
||||||
|
integrity sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==
|
||||||
|
dependencies:
|
||||||
|
universalify "^0.1.2"
|
||||||
|
optionalDependencies:
|
||||||
|
graceful-fs "^4.1.6"
|
||||||
|
|
||||||
jsonfile@^6.0.1:
|
jsonfile@^6.0.1:
|
||||||
version "6.1.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||||
@@ -21498,7 +21522,7 @@ unique-string@^2.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
crypto-random-string "^2.0.0"
|
crypto-random-string "^2.0.0"
|
||||||
|
|
||||||
universalify@^0.1.0:
|
universalify@^0.1.0, universalify@^0.1.2:
|
||||||
version "0.1.2"
|
version "0.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||||
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==
|
||||||
|
|||||||
Reference in New Issue
Block a user