improved EmojiBoard

This commit is contained in:
unknown 2021-08-13 16:31:22 +05:30
parent 4b5553abef
commit 769fd7b524
3 changed files with 87 additions and 28 deletions

View file

@ -30,14 +30,14 @@ const viewEvent = new EventEmitter();
function EmojiGroup({ name, emojis }) { function EmojiGroup({ name, emojis }) {
function getEmojiBoard() { function getEmojiBoard() {
const emojiBoard = [];
const ROW_EMOJIS_COUNT = 7; const ROW_EMOJIS_COUNT = 7;
const emojiRows = [];
const totalEmojis = emojis.length; const totalEmojis = emojis.length;
for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) { for (let r = 0; r < totalEmojis; r += ROW_EMOJIS_COUNT) {
const emojiRow = []; const emojiRow = [];
for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) { for (let c = r; c < r + ROW_EMOJIS_COUNT; c += 1) {
const emojiIndex = r + c; const emojiIndex = c;
if (emojiIndex >= totalEmojis) break; if (emojiIndex >= totalEmojis) break;
const emoji = emojis[emojiIndex]; const emoji = emojis[emojiIndex];
emojiRow.push( emojiRow.push(
@ -49,6 +49,7 @@ function EmojiGroup({ name, emojis }) {
attributes: () => ({ attributes: () => ({
unicode: emoji.unicode, unicode: emoji.unicode,
shortcodes: emoji.shortcodes?.toString(), shortcodes: emoji.shortcodes?.toString(),
hexcode: emoji.hexcode,
}), }),
}, },
)) ))
@ -56,9 +57,9 @@ function EmojiGroup({ name, emojis }) {
</span>, </span>,
); );
} }
emojiRows.push(<div key={r} className="emoji-row">{emojiRow}</div>); emojiBoard.push(<div key={r} className="emoji-row">{emojiRow}</div>);
} }
return emojiRows; return emojiBoard;
} }
return ( return (
@ -73,6 +74,7 @@ EmojiGroup.propTypes = {
emojis: PropTypes.arrayOf(PropTypes.shape({ emojis: PropTypes.arrayOf(PropTypes.shape({
length: PropTypes.number, length: PropTypes.number,
unicode: PropTypes.string, unicode: PropTypes.string,
hexcode: PropTypes.string,
shortcodes: PropTypes.oneOfType([ shortcodes: PropTypes.oneOfType([
PropTypes.string, PropTypes.string,
PropTypes.arrayOf(PropTypes.string), PropTypes.arrayOf(PropTypes.string),
@ -104,16 +106,18 @@ function SearchedEmoji() {
function EmojiBoard({ onSelect }) { function EmojiBoard({ onSelect }) {
const searchRef = useRef(null); const searchRef = useRef(null);
const scrollEmojisRef = useRef(null); const scrollEmojisRef = useRef(null);
const emojiInfo = useRef(null);
function isTargetNotEmoji(target) { function isTargetNotEmoji(target) {
return target.classList.contains('emoji') === false; return target.classList.contains('emoji') === false;
} }
function getEmojiDataFromTarget(target) { function getEmojiDataFromTarget(target) {
const unicode = target.getAttribute('unicode'); const unicode = target.getAttribute('unicode');
const hexcode = target.getAttribute('hexcode');
let shortcodes = target.getAttribute('shortcodes'); let shortcodes = target.getAttribute('shortcodes');
if (typeof shortcodes === 'undefined') shortcodes = undefined; if (typeof shortcodes === 'undefined') shortcodes = undefined;
else shortcodes = shortcodes.split(','); else shortcodes = shortcodes.split(',');
return { unicode, shortcodes }; return { unicode, hexcode, shortcodes };
} }
function selectEmoji(e) { function selectEmoji(e) {
@ -123,18 +127,29 @@ function EmojiBoard({ onSelect }) {
onSelect(getEmojiDataFromTarget(emoji)); onSelect(getEmojiDataFromTarget(emoji));
} }
function setEmojiInfo(emoji) {
const infoEmoji = emojiInfo.current.firstElementChild.firstElementChild;
const infoShortcode = emojiInfo.current.lastElementChild;
const emojiSrc = infoEmoji.src;
infoEmoji.src = `${emojiSrc.slice(0, emojiSrc.lastIndexOf('/') + 1)}${emoji.hexcode.toLowerCase()}.png`;
infoShortcode.textContent = `:${emoji.shortcode}:`;
}
function hoverEmoji(e) { function hoverEmoji(e) {
if (isTargetNotEmoji(e.target)) return; if (isTargetNotEmoji(e.target)) return;
const emoji = e.target; const emoji = e.target;
const { shortcodes } = getEmojiDataFromTarget(emoji); const { shortcodes, hexcode } = getEmojiDataFromTarget(emoji);
if (typeof shortcodes === 'undefined') { if (typeof shortcodes === 'undefined') {
searchRef.current.placeholder = 'Search'; searchRef.current.placeholder = 'Search';
setEmojiInfo({ hexcode: '1f643', shortcode: 'slight_smile' });
return; return;
} }
if (searchRef.current.placeholder === shortcodes[0]) return; if (searchRef.current.placeholder === shortcodes[0]) return;
searchRef.current.setAttribute('placeholder', `:${shortcodes[0]}:`); searchRef.current.setAttribute('placeholder', `:${shortcodes[0]}:`);
setEmojiInfo({ hexcode, shortcode: shortcodes[0] });
} }
function handleSearchChange(e) { function handleSearchChange(e) {
@ -157,7 +172,11 @@ function EmojiBoard({ onSelect }) {
return ( return (
<div id="emoji-board" className="emoji-board"> <div id="emoji-board" className="emoji-board">
<div className="emoji-board__content"> <div className="emoji-board__content">
<div className="emoji-board__emojis"> <div className="emoji-board__content__search">
<RawIcon size="small" src={SearchIC} />
<Input onChange={handleSearchChange} forwardRef={searchRef} placeholder="Search" />
</div>
<div className="emoji-board__content__emojis">
<ScrollView ref={scrollEmojisRef} autoHide> <ScrollView ref={scrollEmojisRef} autoHide>
<div onMouseMove={hoverEmoji} onClick={selectEmoji}> <div onMouseMove={hoverEmoji} onClick={selectEmoji}>
<SearchedEmoji /> <SearchedEmoji />
@ -169,9 +188,9 @@ function EmojiBoard({ onSelect }) {
</div> </div>
</ScrollView> </ScrollView>
</div> </div>
<div className="emoji-board__search"> <div ref={emojiInfo} className="emoji-board__content__info">
<RawIcon size="small" src={SearchIC} /> <div>{ parse(twemoji.parse('🙂')) }</div>
<Input onChange={handleSearchChange} forwardRef={searchRef} placeholder="Search" /> <Text>:slight_smile:</Text>
</div> </div>
</div> </div>
<div className="emoji-board__nav"> <div className="emoji-board__nav">

View file

@ -10,14 +10,15 @@
.emoji-board { .emoji-board {
display: flex; display: flex;
&__content { &__content {
@extend .emoji-board-flexItem; @extend .emoji-board-flexItem;
@extend .emoji-board-flexBoxV; @extend .emoji-board-flexBoxV;
height: 360px; height: 400px;
width: 286px;
} }
&__nav { &__nav {
@extend .emoji-board-flexBoxV; @extend .emoji-board-flexBoxV;
justify-content: center;
padding: 4px 6px; padding: 4px 6px;
background-color: var(--bg-surface-low); background-color: var(--bg-surface-low);
@ -29,30 +30,62 @@
& > .ic-btn-surface { & > .ic-btn-surface {
margin: calc(var(--sp-ultra-tight) / 2) 0; margin: calc(var(--sp-ultra-tight) / 2) 0;
opacity: 0.8;
} }
} }
} }
.emoji-board__content__search {
padding: var(--sp-extra-tight);
position: relative;
.emoji-board__emojis { & .ic-raw {
@extend .emoji-board-flexItem; position: absolute;
left: var(--sp-normal);
top: var(--sp-normal);
transform: translateY(1px);
[dir=rtl] & {
left: unset;
right: var(--sp-normal);
}
} }
.emoji-board__search {
display: flex;
align-items: center;
padding: calc(var(--sp-ultra-tight) / 2) var(--sp-normal);
& .input-container { & .input-container {
@extend .emoji-board-flexItem;
& .input { & .input {
min-width: 100%; min-width: 100%;
width: 0; width: 0;
background-color: transparent; padding: var(--sp-extra-tight) 36px;
border: none !important; border-radius: calc(var(--bo-radius) / 2);
box-shadow: none !important;
} }
} }
} }
.emoji-board__content__emojis {
@extend .emoji-board-flexItem;
@extend .emoji-board-flexBoxV;
}
.emoji-board__content__info {
margin: 0 var(--sp-extra-tight);
padding: var(--sp-tight) var(--sp-extra-tight);
border-top: 1px solid var(--bg-surface-border);
display: flex;
align-items: center;
& > div:first-child {
line-height: 0;
.emoji {
width: 32px;
height: 32px;
}
}
& > p:last-child {
@extend .emoji-board-flexItem;
margin: 0 var(--sp-tight);
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
}
.emoji-group { .emoji-group {
--emoji-padding: 6px; --emoji-padding: 6px;
@ -65,12 +98,19 @@
z-index: 99; z-index: 99;
background-color: var(--bg-surface); background-color: var(--bg-surface);
padding: var(--sp-tight) var(--sp-normal); margin-left: var(--sp-extra-tight);
padding: var(--sp-extra-tight) var(--sp-ultra-tight);
text-transform: uppercase; text-transform: uppercase;
font-weight: 600; font-weight: 600;
box-shadow: 0 -4px 0 0 var(--bg-surface);
border-bottom: 1px solid var(--bg-surface-border);
[dir=rtl] & {
margin-left: 0;
margin-right: var(--sp-extra-tight);
}
} }
& .emoji-set { & .emoji-set {
margin: 0 calc(var(--sp-normal) - var(--emoji-padding)); margin: var(--sp-extra-tight) calc(var(--sp-normal) - var(--emoji-padding));
margin-right: calc(var(--sp-extra-tight) - var(--emoji-padding)); margin-right: calc(var(--sp-extra-tight) - var(--emoji-padding));
[dir=rtl] & { [dir=rtl] & {
margin-right: calc(var(--sp-normal) - var(--emoji-padding)); margin-right: calc(var(--sp-normal) - var(--emoji-padding));
@ -79,6 +119,7 @@
} }
& .emoji { & .emoji {
width: 38px; width: 38px;
height: 38px;
padding: var(--emoji-padding); padding: var(--emoji-padding);
cursor: pointer; cursor: pointer;
&:hover { &:hover {

View file

@ -47,7 +47,7 @@ function addToGroup(emoji) {
else if (emoji.group === 6) addEmoji(emoji, 3); else if (emoji.group === 6) addEmoji(emoji, 3);
else if (emoji.group === 5) addEmoji(emoji, 4); else if (emoji.group === 5) addEmoji(emoji, 4);
else if (emoji.group === 7) addEmoji(emoji, 5); else if (emoji.group === 7) addEmoji(emoji, 5);
else if (emoji.group === 8) addEmoji(emoji, 6); else if (emoji.group === 8 || typeof emoji.group === 'undefined') addEmoji(emoji, 6);
else if (emoji.group === 9) addEmoji(emoji, 7); else if (emoji.group === 9) addEmoji(emoji, 7);
} }
@ -70,7 +70,6 @@ function searchEmoji(term) {
if (result.length > 20) result = result.slice(0, 20); if (result.length > 20) result = result.slice(0, 20);
return result; return result;
} }
export { export {
emojis, emojiGroups, searchEmoji, emojis, emojiGroups, searchEmoji,
}; };