fix(emoji): make emoji picker more like Mastodon's (#842)
This commit is contained in:
parent
cd44e33a7e
commit
7596d905ab
|
@ -4,7 +4,7 @@
|
|||
{title}
|
||||
background="var(--main-bg)"
|
||||
>
|
||||
<div class="emoji-container" {style} >
|
||||
<div class="emoji-container" {style} ref:container >
|
||||
{#if loaded}
|
||||
<emoji-mart props-json={emojiMartPropsJson} ></emoji-mart>
|
||||
{:elseif error}
|
||||
|
@ -37,6 +37,30 @@
|
|||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
:global(.emoji-container .emoji-mart-category .emoji-mart-emoji span, .emoji-container .emoji-mart-anchor) {
|
||||
cursor: pointer;
|
||||
}
|
||||
:global(.emoji-container .emoji-mart-search-icon) {
|
||||
top: 6px; /* this looks a bit off-center with the native emoji */
|
||||
}
|
||||
|
||||
:global(.emoji-container .emoji-mart-skin) {
|
||||
max-width: 24px;
|
||||
}
|
||||
|
||||
:global(.emoji-container .emoji-mart-skin-swatch.selected) {
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
:global(.emoji-container .emoji-mart-skin-swatches.opened .emoji-mart-skin-swatch) {
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
@media (max-width: 320px) {
|
||||
:global(.emoji-container .emoji-mart-preview) {
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import ModalDialog from './ModalDialog.html'
|
||||
|
@ -50,6 +74,21 @@
|
|||
import { on } from '../../../_utils/eventBus'
|
||||
import { createEmojiMartPicker } from '../../../_react/createEmojiMartPicker'
|
||||
|
||||
// Consistency with Mastodon FE, taken from
|
||||
// app/javascript/mastodon/features/compose/components/emoji_picker_dropdown.js
|
||||
const categoriesSort = [
|
||||
'recent',
|
||||
'custom',
|
||||
'people',
|
||||
'nature',
|
||||
'foods',
|
||||
'activity',
|
||||
'places',
|
||||
'objects',
|
||||
'symbols',
|
||||
'flags'
|
||||
]
|
||||
|
||||
export default {
|
||||
async oncreate () {
|
||||
onCreateDialog.call(this)
|
||||
|
@ -60,6 +99,16 @@
|
|||
define({ 'emoji-mart': Picker })
|
||||
}
|
||||
this.set({ loaded: true })
|
||||
requestAnimationFrame(() => {
|
||||
let container = this.refs.container
|
||||
if (container) {
|
||||
let searchInput = container.querySelector('emoji-mart .emoji-mart-search input')
|
||||
if (searchInput) {
|
||||
// do this manually because emoji-mart's built in autofocus doesn't work consistently
|
||||
searchInput.focus()
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
this.set({ error }) // should never happen, but you never know
|
||||
}
|
||||
|
@ -81,16 +130,25 @@
|
|||
min-height: ${$isSmallMobileSize ? 300 : 400}px;
|
||||
`),
|
||||
emojiMartPropsJson: ({ emojiMartProps }) => JSON.stringify(emojiMartProps),
|
||||
emojiMartProps: ({ perLine, custom, showPreview }) => ({
|
||||
emojiMartProps: ({ perLine, custom }) => ({
|
||||
perLine,
|
||||
custom,
|
||||
showPreview,
|
||||
color: 'var(--nav-bg)',
|
||||
emoji: 'sailboat',
|
||||
title: 'Emoji'
|
||||
title: 'Emoji',
|
||||
include: categoriesSort,
|
||||
showPreview: true,
|
||||
autoFocus: true
|
||||
}),
|
||||
showPreview: ({ $isSmallMobileSize }) => !$isSmallMobileSize,
|
||||
perLine: ({ $isSmallMobileSize }) => $isSmallMobileSize ? 7 : 9,
|
||||
perLine: ({ $isSmallMobileSize, $isTinyMobileSize, $isMobileSize }) => (
|
||||
$isTinyMobileSize
|
||||
? 7
|
||||
: $isSmallMobileSize
|
||||
? 8
|
||||
: $isMobileSize
|
||||
? 9
|
||||
: 10
|
||||
),
|
||||
custom: ({ $currentCustomEmoji, $autoplayGifs }) => {
|
||||
if (!$currentCustomEmoji) {
|
||||
return []
|
||||
|
|
|
@ -123,6 +123,17 @@
|
|||
:global(body.modal-open) {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
@media (max-width: 320px) {
|
||||
.modal-dialog-title {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
.close-dialog-button-svg {
|
||||
padding: 7px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import { A11yDialog } from '../../../_thirdparty/a11y-dialog/a11y-dialog'
|
||||
|
|
|
@ -13,8 +13,8 @@ function onEmojiSelected (emoji) {
|
|||
|
||||
export default function createEmojiMartPickerFromData (data) {
|
||||
return props => React.createElement(NimblePicker, Object.assign({
|
||||
set: 'all',
|
||||
data,
|
||||
set: 'twitter', // same as Mastodon frontend
|
||||
data, // same as Mastodon frontend
|
||||
native: true,
|
||||
onSelect: onEmojiSelected
|
||||
}, props))
|
||||
|
|
|
@ -7,8 +7,9 @@ export function resizeObservers (store) {
|
|||
|
||||
const recalculateIsMobileSize = () => {
|
||||
store.set({
|
||||
isMobileSize: window.matchMedia('(max-width: 767px)').matches,
|
||||
isSmallMobileSize: window.matchMedia('(max-width: 479px)').matches
|
||||
isMobileSize: window.matchMedia('(max-width: 767px)').matches, // e.g. iPhone Plus
|
||||
isSmallMobileSize: window.matchMedia('(max-width: 479px)').matches, // e.g. Galaxy S5
|
||||
isTinyMobileSize: window.matchMedia('(max-width: 320px)').matches // e.g. iPhone 4
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue