You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			144 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			144 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			TypeScript
		
	
| import React, { forwardRef, useEffect, useState } from 'react';
 | |
| import classNames from 'classnames';
 | |
| import styled from 'styled-components';
 | |
| // @ts-ignore
 | |
| import Picker from '@emoji-mart/react';
 | |
| import { useSelector } from 'react-redux';
 | |
| import { getTheme } from '../../state/selectors/theme';
 | |
| import { FixedBaseEmoji, FixedPickerProps } from '../../types/Reaction';
 | |
| import { COLORS, PrimaryColorStateType, THEMES, ThemeStateType } from '../../themes/colors.js';
 | |
| import { hexColorToRGB } from '../../util/hexColorToRGB';
 | |
| import { getPrimaryColor } from '../../state/selectors/primaryColor';
 | |
| import { i18nEmojiData } from '../../util/emoji';
 | |
| 
 | |
| export const StyledEmojiPanel = styled.div<{
 | |
|   isModal: boolean;
 | |
|   primaryColor: PrimaryColorStateType;
 | |
|   theme: ThemeStateType;
 | |
|   panelBackgroundRGB: string;
 | |
|   panelTextRGB: string;
 | |
| }>`
 | |
|   padding: var(--margins-lg);
 | |
|   z-index: 5;
 | |
|   opacity: 0;
 | |
|   visibility: hidden;
 | |
|   // this disables the slide-in animation when showing the emoji picker from a right click on a message
 | |
|   /* transition: var(--default-duration); */
 | |
| 
 | |
|   button:focus {
 | |
|     outline: none;
 | |
|   }
 | |
| 
 | |
|   &.show {
 | |
|     opacity: 1;
 | |
|     visibility: visible;
 | |
|   }
 | |
| 
 | |
|   em-emoji-picker {
 | |
|     ${props => props.panelBackgroundRGB && `background-color: rgb(${props.panelBackgroundRGB})`};
 | |
|     border: 1px solid var(--border-color);
 | |
|     padding-bottom: var(--margins-sm);
 | |
|     --font-family: var(--font-default);
 | |
|     --font-size: var(--font-size-sm);
 | |
|     --shadow: none;
 | |
|     --border-radius: 8px;
 | |
|     --color-border: var(--border-color);
 | |
|     --color-border-over: var(--border-color);
 | |
|     --background-rgb: ${props => props.panelBackgroundRGB};
 | |
|     --rgb-background: ${props => props.panelBackgroundRGB};
 | |
|     --rgb-color: ${props => props.panelTextRGB};
 | |
|     --rgb-input: ${props => props.panelBackgroundRGB};
 | |
|     --rgb-accent: ${props =>
 | |
|       hexColorToRGB(
 | |
|         props.primaryColor
 | |
|           ? (COLORS.PRIMARY as any)[`${props.primaryColor.toUpperCase()}`]
 | |
|           : COLORS.PRIMARY.GREEN
 | |
|       )};
 | |
| 
 | |
|     ${props =>
 | |
|       !props.isModal &&
 | |
|       `
 | |
|       &:after {
 | |
|         content: '';
 | |
|         position: absolute;
 | |
|         top: calc(100% - 40px);
 | |
|         left: calc(100% - 79px);
 | |
|         width: 22px;
 | |
|         height: 22px;
 | |
|         transform: rotate(45deg);
 | |
|         border-radius: 3px;
 | |
|         transform: scaleY(1.4) rotate(45deg);
 | |
|         border: 0.7px solid var(--border-color);
 | |
|         clip-path: polygon(100% 100%, 7.2px 100%, 100% 7.2px);
 | |
|         ${props.panelBackgroundRGB && `background-color: rgb(${props.panelBackgroundRGB})`};
 | |
|       }
 | |
|     `};
 | |
|   }
 | |
| `;
 | |
| 
 | |
| type Props = {
 | |
|   onEmojiClicked: (emoji: FixedBaseEmoji) => void;
 | |
|   show: boolean;
 | |
|   isModal?: boolean;
 | |
|   // NOTE Currently this doesn't work but we have a PR waiting to be merged to resolve this. William Grant 30/09/2022
 | |
|   onKeyDown?: (event: any) => void;
 | |
| };
 | |
| 
 | |
| const pickerProps: FixedPickerProps = {
 | |
|   title: '',
 | |
|   showPreview: true,
 | |
|   autoFocus: true,
 | |
|   skinTonePosition: 'preview',
 | |
| };
 | |
| 
 | |
| export const SessionEmojiPanel = forwardRef<HTMLDivElement, Props>((props: Props, ref) => {
 | |
|   const { onEmojiClicked, show, isModal = false, onKeyDown } = props;
 | |
|   const primaryColor = useSelector(getPrimaryColor);
 | |
|   const theme = useSelector(getTheme);
 | |
| 
 | |
|   const [panelBackgroundRGB, setPanelBackgroundRGB] = useState('');
 | |
|   const [panelTextRGB, setPanelTextRGB] = useState('');
 | |
| 
 | |
|   useEffect(() => {
 | |
|     switch (theme) {
 | |
|       case 'ocean-dark':
 | |
|         setPanelBackgroundRGB(hexColorToRGB(THEMES.OCEAN_DARK.COLOR1));
 | |
|         setPanelTextRGB(hexColorToRGB(THEMES.OCEAN_DARK.COLOR6));
 | |
|         break;
 | |
|       case 'ocean-light':
 | |
|         setPanelBackgroundRGB(hexColorToRGB(THEMES.OCEAN_LIGHT.COLOR7!));
 | |
|         setPanelTextRGB(hexColorToRGB(THEMES.OCEAN_LIGHT.COLOR1));
 | |
|         break;
 | |
|       case 'classic-dark':
 | |
|         setPanelBackgroundRGB(hexColorToRGB(THEMES.CLASSIC_DARK.COLOR1));
 | |
|         setPanelTextRGB(hexColorToRGB(THEMES.CLASSIC_DARK.COLOR6));
 | |
|         break;
 | |
|       case 'classic-light':
 | |
|       default:
 | |
|         setPanelBackgroundRGB(hexColorToRGB(THEMES.CLASSIC_LIGHT.COLOR6));
 | |
|         setPanelTextRGB(hexColorToRGB(THEMES.CLASSIC_LIGHT.COLOR0));
 | |
|         break;
 | |
|     }
 | |
|   }, [theme]);
 | |
| 
 | |
|   return (
 | |
|     <StyledEmojiPanel
 | |
|       isModal={isModal}
 | |
|       primaryColor={primaryColor}
 | |
|       theme={theme}
 | |
|       panelBackgroundRGB={panelBackgroundRGB}
 | |
|       panelTextRGB={panelTextRGB}
 | |
|       className={classNames(show && 'show')}
 | |
|       ref={ref}
 | |
|     >
 | |
|       <Picker
 | |
|         theme={theme.includes('light') ? 'light' : 'dark'}
 | |
|         i18n={i18nEmojiData}
 | |
|         onEmojiSelect={onEmojiClicked}
 | |
|         onKeyDown={onKeyDown}
 | |
|         {...pickerProps}
 | |
|       />
 | |
|     </StyledEmojiPanel>
 | |
|   );
 | |
| });
 |