Add navigation bar to sticker board
This commit is contained in:
parent
3c1cc59d59
commit
1da3d252e8
4 changed files with 103 additions and 57 deletions
|
@ -252,6 +252,58 @@ function EmojiBoard({ onSelect, searchRef }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div id="emoji-board" className="emoji-board">
|
<div id="emoji-board" className="emoji-board">
|
||||||
|
<ScrollView invisible>
|
||||||
|
<div className="emoji-board__nav">
|
||||||
|
{recentEmojis.length > 0 && (
|
||||||
|
<IconButton
|
||||||
|
onClick={() => openGroup(0)}
|
||||||
|
src={RecentClockIC}
|
||||||
|
tooltip="Recent"
|
||||||
|
tooltipPlacement="left"
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<div className="emoji-board__nav-custom">
|
||||||
|
{
|
||||||
|
availableEmojis.map((pack) => {
|
||||||
|
const src = initMatrix.matrixClient
|
||||||
|
.mxcUrlToHttp(pack.avatarUrl ?? pack.getEmojis()[0].mxc);
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
onClick={() => openGroup(recentOffset + pack.packIndex)}
|
||||||
|
src={src}
|
||||||
|
key={pack.packIndex}
|
||||||
|
tooltip={pack.displayName ?? 'Unknown'}
|
||||||
|
tooltipPlacement="left"
|
||||||
|
isImage
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div className="emoji-board__nav-twemoji">
|
||||||
|
{
|
||||||
|
[
|
||||||
|
[0, EmojiIC, 'Smilies'],
|
||||||
|
[1, DogIC, 'Animals'],
|
||||||
|
[2, CupIC, 'Food'],
|
||||||
|
[3, BallIC, 'Activities'],
|
||||||
|
[4, PhotoIC, 'Travel'],
|
||||||
|
[5, BulbIC, 'Objects'],
|
||||||
|
[6, PeaceIC, 'Symbols'],
|
||||||
|
[7, FlagIC, 'Flags'],
|
||||||
|
].map(([indx, ico, name]) => (
|
||||||
|
<IconButton
|
||||||
|
onClick={() => openGroup(recentOffset + availableEmojis.length + indx)}
|
||||||
|
key={indx}
|
||||||
|
src={ico}
|
||||||
|
tooltip={name}
|
||||||
|
tooltipPlacement="left"
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ScrollView>
|
||||||
<div className="emoji-board__content">
|
<div className="emoji-board__content">
|
||||||
<div className="emoji-board__content__search">
|
<div className="emoji-board__content__search">
|
||||||
<RawIcon size="small" src={SearchIC} />
|
<RawIcon size="small" src={SearchIC} />
|
||||||
|
@ -285,58 +337,6 @@ function EmojiBoard({ onSelect, searchRef }) {
|
||||||
<Text>:slight_smile:</Text>
|
<Text>:slight_smile:</Text>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ScrollView invisible>
|
|
||||||
<div className="emoji-board__nav">
|
|
||||||
{recentEmojis.length > 0 && (
|
|
||||||
<IconButton
|
|
||||||
onClick={() => openGroup(0)}
|
|
||||||
src={RecentClockIC}
|
|
||||||
tooltip="Recent"
|
|
||||||
tooltipPlacement="right"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div className="emoji-board__nav-custom">
|
|
||||||
{
|
|
||||||
availableEmojis.map((pack) => {
|
|
||||||
const src = initMatrix.matrixClient
|
|
||||||
.mxcUrlToHttp(pack.avatarUrl ?? pack.getEmojis()[0].mxc);
|
|
||||||
return (
|
|
||||||
<IconButton
|
|
||||||
onClick={() => openGroup(recentOffset + pack.packIndex)}
|
|
||||||
src={src}
|
|
||||||
key={pack.packIndex}
|
|
||||||
tooltip={pack.displayName ?? 'Unknown'}
|
|
||||||
tooltipPlacement="right"
|
|
||||||
isImage
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className="emoji-board__nav-twemoji">
|
|
||||||
{
|
|
||||||
[
|
|
||||||
[0, EmojiIC, 'Smilies'],
|
|
||||||
[1, DogIC, 'Animals'],
|
|
||||||
[2, CupIC, 'Food'],
|
|
||||||
[3, BallIC, 'Activities'],
|
|
||||||
[4, PhotoIC, 'Travel'],
|
|
||||||
[5, BulbIC, 'Objects'],
|
|
||||||
[6, PeaceIC, 'Symbols'],
|
|
||||||
[7, FlagIC, 'Flags'],
|
|
||||||
].map(([indx, ico, name]) => (
|
|
||||||
<IconButton
|
|
||||||
onClick={() => openGroup(recentOffset + availableEmojis.length + indx)}
|
|
||||||
key={indx}
|
|
||||||
src={ico}
|
|
||||||
tooltip={name}
|
|
||||||
tooltipPlacement="right"
|
|
||||||
/>
|
|
||||||
))
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ScrollView>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
padding: 4px 6px;
|
padding: 4px 6px;
|
||||||
background-color: var(--bg-surface-low);
|
background-color: var(--bg-surface-low);
|
||||||
@include dir.side(border, 1px solid var(--bg-surface-border), none);
|
@include dir.side(border, none, 1px solid var(--bg-surface-border));
|
||||||
|
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@ -122,8 +122,11 @@
|
||||||
@include dir.side(margin, var(--left-margin), var(--right-margin));
|
@include dir.side(margin, var(--left-margin), var(--right-margin));
|
||||||
}
|
}
|
||||||
& .emoji {
|
& .emoji {
|
||||||
width: 38px;
|
max-width: 38px;
|
||||||
height: 38px;
|
max-height: 38px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
padding: var(--emoji-padding);
|
padding: var(--emoji-padding);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
/* eslint-disable jsx-a11y/click-events-have-key-events */
|
||||||
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
/* eslint-disable jsx-a11y/no-static-element-interactions */
|
||||||
import React from 'react';
|
import React, { useRef } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import './StickerBoard.scss';
|
import './StickerBoard.scss';
|
||||||
|
|
||||||
|
@ -9,10 +9,12 @@ import { getRelevantPacks } from '../emoji-board/custom-emoji';
|
||||||
|
|
||||||
import Text from '../../atoms/text/Text';
|
import Text from '../../atoms/text/Text';
|
||||||
import ScrollView from '../../atoms/scroll/ScrollView';
|
import ScrollView from '../../atoms/scroll/ScrollView';
|
||||||
|
import IconButton from '../../atoms/button/IconButton';
|
||||||
|
|
||||||
function StickerBoard({ roomId, onSelect }) {
|
function StickerBoard({ roomId, onSelect }) {
|
||||||
const mx = initMatrix.matrixClient;
|
const mx = initMatrix.matrixClient;
|
||||||
const room = mx.getRoom(roomId);
|
const room = mx.getRoom(roomId);
|
||||||
|
const scrollRef = useRef(null);
|
||||||
|
|
||||||
const parentIds = initMatrix.roomList.getAllParentSpaces(room.roomId);
|
const parentIds = initMatrix.roomList.getAllParentSpaces(room.roomId);
|
||||||
const parentRooms = [...parentIds].map((id) => mx.getRoom(id));
|
const parentRooms = [...parentIds].map((id) => mx.getRoom(id));
|
||||||
|
@ -38,6 +40,11 @@ function StickerBoard({ roomId, onSelect }) {
|
||||||
onSelect(stickerData);
|
onSelect(stickerData);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openGroup = (groupIndex) => {
|
||||||
|
const scrollContent = scrollRef.current.firstElementChild;
|
||||||
|
scrollContent.children[groupIndex].scrollIntoView();
|
||||||
|
};
|
||||||
|
|
||||||
const renderPack = (pack) => (
|
const renderPack = (pack) => (
|
||||||
<div className="sticker-board__pack" key={pack.id}>
|
<div className="sticker-board__pack" key={pack.id}>
|
||||||
<Text className="sticker-board__pack-header" variant="b2" weight="bold">{pack.displayName ?? 'Unknown'}</Text>
|
<Text className="sticker-board__pack-header" variant="b2" weight="bold">{pack.displayName ?? 'Unknown'}</Text>
|
||||||
|
@ -50,6 +57,7 @@ function StickerBoard({ roomId, onSelect }) {
|
||||||
alt={sticker.shortcode}
|
alt={sticker.shortcode}
|
||||||
title={sticker.body ?? sticker.shortcode}
|
title={sticker.body ?? sticker.shortcode}
|
||||||
data-mx-sticker={sticker.mxc}
|
data-mx-sticker={sticker.mxc}
|
||||||
|
loading="lazy"
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -58,8 +66,27 @@ function StickerBoard({ roomId, onSelect }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="sticker-board">
|
<div className="sticker-board">
|
||||||
|
{packs.length > 0 && (
|
||||||
|
<ScrollView invisible>
|
||||||
|
<div className="sticker-board__sidebar">
|
||||||
|
{packs.map((pack, index) => {
|
||||||
|
const src = mx.mxcUrlToHttp(pack.avatarUrl ?? pack.getStickers()[0].mxc);
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
key={pack.id}
|
||||||
|
onClick={() => openGroup(index)}
|
||||||
|
src={src}
|
||||||
|
tooltip={pack.displayName || 'Unknown'}
|
||||||
|
tooltipPlacement="left"
|
||||||
|
isImage
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</ScrollView>
|
||||||
|
)}
|
||||||
<div className="sticker-board__container">
|
<div className="sticker-board__container">
|
||||||
<ScrollView autoHide>
|
<ScrollView autoHide ref={scrollRef}>
|
||||||
<div
|
<div
|
||||||
onClick={handleOnSelect}
|
onClick={handleOnSelect}
|
||||||
className="sticker-board__content"
|
className="sticker-board__content"
|
||||||
|
|
|
@ -5,6 +5,22 @@
|
||||||
--sticker-board-width: 286px;
|
--sticker-board-width: 286px;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: var(--sticker-board-height);
|
height: var(--sticker-board-height);
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
& > .scrollbar {
|
||||||
|
width: initial;
|
||||||
|
height: var(--sticker-board-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
&__sidebar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100%;
|
||||||
|
padding: 4px 6px;
|
||||||
|
|
||||||
|
background-color: var(--bg-surface-low);
|
||||||
|
@include dir.side(border, none, 1px solid var(--bg-surface-border));
|
||||||
|
}
|
||||||
|
|
||||||
&__container {
|
&__container {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
|
Loading…
Reference in a new issue