diff --git a/web/src/components/EmojiPicker.js b/web/src/components/EmojiPicker.js index 27821f9a..6bbf695f 100644 --- a/web/src/components/EmojiPicker.js +++ b/web/src/components/EmojiPicker.js @@ -1,8 +1,13 @@ import * as React from 'react'; +import {useRef, useState} from 'react'; import Popover from '@mui/material/Popover'; import Typography from '@mui/material/Typography'; import {rawEmojis} from '../app/emojis'; import Box from "@mui/material/Box"; +import TextField from "@mui/material/TextField"; +import {InputAdornment} from "@mui/material"; +import IconButton from "@mui/material/IconButton"; +import {Close} from "@mui/icons-material"; const emojisByCategory = {}; rawEmojis.forEach(emoji => { @@ -14,22 +19,69 @@ rawEmojis.forEach(emoji => { const EmojiPicker = (props) => { const open = Boolean(props.anchorEl); + const [search, setSearch] = useState(""); + const searchRef = useRef(null); + + /* + FIXME Search is inefficient, somehow make it faster + + useEffect(() => { + const matching = rawEmojis.filter(e => { + const searchLower = search.toLowerCase(); + return e.description.toLowerCase().indexOf(searchLower) !== -1 + || matchInArray(e.aliases, searchLower) + || matchInArray(e.tags, searchLower); + }); + console.log("matching", matching.length); + }, [search]); + */ + const handleSearchClear = () => { + setSearch(""); + searchRef.current?.focus(); + }; return ( <> - {Object.keys(emojisByCategory).map(category => - - )} + setSearch(ev.target.value)} + type="text" + variant="standard" + fullWidth + sx={{ marginTop: 0, paddingRight: 2 }} + InputProps={{ + endAdornment: + + + + }} + /> + + {Object.keys(emojisByCategory).map(category => + + )} + @@ -37,18 +89,36 @@ const EmojiPicker = (props) => { }; const Category = (props) => { + const showTitle = !props.search; return ( <> - {props.title} - - {props.emojis.map(emoji => props.onPick(emoji.aliases[0])}/>)} - + {showTitle && + + {props.title} + + } + {props.emojis.map(emoji => + props.onPick(emoji.aliases[0])} + /> + )} ); }; const Emoji = (props) => { const emoji = props.emoji; + const search = props.search; + const matches = search === "" + || emoji.description.toLowerCase().indexOf(search) !== -1 + || matchInArray(emoji.aliases, search) + || matchInArray(emoji.tags, search); + if (!matches) { + return null; + } return (
{ ); }; +const matchInArray = (arr, search) => { + if (!arr || !search) { + return false; + } + return arr.filter(s => s.indexOf(search) !== -1).length > 0; +} + export default EmojiPicker; diff --git a/web/src/components/SendDialog.js b/web/src/components/SendDialog.js index 0607c9a3..1a55d127 100644 --- a/web/src/components/SendDialog.js +++ b/web/src/components/SendDialog.js @@ -213,11 +213,11 @@ const SendDialog = (props) => { onDragLeave={handleAttachFileDragLeave}/> } - Publish to {shortUrl(topicUrl)} + {topicUrl ? `Publish to ${shortUrl(topicUrl)}` : "Publish message"} {dropZone && } {showTopicUrl && - { + { setTopicUrl(props.topicUrl); setShowTopicUrl(false); }}> @@ -468,10 +468,11 @@ const Row = (props) => { }; const ClosableRow = (props) => { + const closable = (props.hasOwnProperty("closable")) ? props.closable : true; return ( {props.children} - + {closable && } ); }; diff --git a/web/src/components/SubscribeDialog.js b/web/src/components/SubscribeDialog.js index 55836d0b..5ed75207 100644 --- a/web/src/components/SubscribeDialog.js +++ b/web/src/components/SubscribeDialog.js @@ -3,7 +3,6 @@ import {useState} from 'react'; import Button from '@mui/material/Button'; import TextField from '@mui/material/TextField'; import Dialog from '@mui/material/Dialog'; -import DialogActions from '@mui/material/DialogActions'; import DialogContent from '@mui/material/DialogContent'; import DialogContentText from '@mui/material/DialogContentText'; import DialogTitle from '@mui/material/DialogTitle'; @@ -11,7 +10,6 @@ import {Autocomplete, Checkbox, FormControlLabel, useMediaQuery} from "@mui/mate import theme from "./theme"; import api from "../app/Api"; import {topicUrl, validTopic, validUrl} from "../app/utils"; -import Box from "@mui/material/Box"; import userManager from "../app/UserManager"; import subscriptionManager from "../app/SubscriptionManager"; import poller from "../app/Poller";