| 
									
										
										
										
											2023-01-03 11:55:46 -08:00
										 |  |  | // Copyright 2018 Signal Messenger, LLC
 | 
					
						
							| 
									
										
										
										
											2020-10-30 15:34:04 -05:00
										 |  |  | // SPDX-License-Identifier: AGPL-3.0-only
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  | import React from 'react'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-22 12:31:43 -07:00
										 |  |  | import classNames from 'classnames'; | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-26 14:15:33 -05:00
										 |  |  | import type { RenderTextCallbackType } from '../../types/Util'; | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  | import { splitByEmoji } from '../../util/emoji'; | 
					
						
							|  |  |  | import { missingCaseError } from '../../util/missingCaseError'; | 
					
						
							| 
									
										
										
										
											2021-10-26 14:15:33 -05:00
										 |  |  | import type { SizeClassType } from '../emoji/lib'; | 
					
						
							|  |  |  | import { emojiToImage } from '../emoji/lib'; | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | // Some of this logic taken from emoji-js/replacement
 | 
					
						
							| 
									
										
										
										
											2020-11-06 12:11:18 -08:00
										 |  |  | // the DOM structure for this getImageTag should match the other emoji implementations:
 | 
					
						
							|  |  |  | // ts/components/emoji/Emoji.tsx
 | 
					
						
							|  |  |  | // ts/quill/emoji/blot.tsx
 | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  | function getImageTag({ | 
					
						
							|  |  |  |   match, | 
					
						
							|  |  |  |   sizeClass, | 
					
						
							|  |  |  |   key, | 
					
						
							|  |  |  | }: { | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  |   match: string; | 
					
						
							| 
									
										
										
										
											2019-01-02 11:56:33 -08:00
										 |  |  |   sizeClass?: SizeClassType; | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  |   key: string | number; | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  | }): JSX.Element | string { | 
					
						
							|  |  |  |   const img = emojiToImage(match); | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 12:28:44 -04:00
										 |  |  |   if (!img) { | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  |     return match; | 
					
						
							| 
									
										
										
										
											2019-06-17 14:46:42 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  |   return ( | 
					
						
							|  |  |  |     <img | 
					
						
							|  |  |  |       key={key} | 
					
						
							| 
									
										
										
										
											2019-07-25 12:28:44 -04:00
										 |  |  |       src={img} | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  |       aria-label={match} | 
					
						
							| 
									
										
										
										
											2018-05-22 12:31:43 -07:00
										 |  |  |       className={classNames('emoji', sizeClass)} | 
					
						
							| 
									
										
										
										
											2021-07-02 15:16:55 -05:00
										 |  |  |       alt={match} | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  |     /> | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-14 12:07:05 -06:00
										 |  |  | export type Props = { | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  |   text: string; | 
					
						
							| 
									
										
										
										
											2018-05-18 14:48:20 -07:00
										 |  |  |   /** A class name to be added to the generated emoji images */ | 
					
						
							| 
									
										
										
										
											2019-01-02 11:56:33 -08:00
										 |  |  |   sizeClass?: SizeClassType; | 
					
						
							| 
									
										
										
										
											2018-05-18 14:48:20 -07:00
										 |  |  |   /** Allows you to customize now non-newlines are rendered. Simplest is just a <span>. */ | 
					
						
							| 
									
										
										
										
											2019-01-14 13:49:58 -08:00
										 |  |  |   renderNonEmoji?: RenderTextCallbackType; | 
					
						
							| 
									
										
										
										
											2021-01-14 12:07:05 -06:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-09 20:59:36 -08:00
										 |  |  | const defaultRenderNonEmoji: RenderTextCallbackType = ({ text }) => text; | 
					
						
							| 
									
										
										
										
											2018-05-18 14:48:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-09 20:59:36 -08:00
										 |  |  | export class Emojify extends React.Component<Props> { | 
					
						
							| 
									
										
										
										
											2021-11-12 17:44:20 -06:00
										 |  |  |   public override render(): null | Array<JSX.Element | string | null> { | 
					
						
							| 
									
										
										
										
											2022-11-09 20:59:36 -08:00
										 |  |  |     const { | 
					
						
							|  |  |  |       text, | 
					
						
							|  |  |  |       sizeClass, | 
					
						
							|  |  |  |       renderNonEmoji = defaultRenderNonEmoji, | 
					
						
							|  |  |  |     } = this.props; | 
					
						
							| 
									
										
										
										
											2018-05-18 14:48:20 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  |     return splitByEmoji(text).map(({ type, value: match }, index) => { | 
					
						
							|  |  |  |       if (type === 'emoji') { | 
					
						
							|  |  |  |         return getImageTag({ match, sizeClass, key: index }); | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  |       } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  |       if (type === 'text') { | 
					
						
							|  |  |  |         return renderNonEmoji({ text: match, key: index }); | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-30 10:00:02 -07:00
										 |  |  |       throw missingCaseError(type); | 
					
						
							|  |  |  |     }); | 
					
						
							| 
									
										
										
										
											2018-05-14 13:52:10 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | } |