fix(emoji): make emoji picker more like Mastodon's (#842)

This commit is contained in:
Nolan Lawson 2018-12-18 18:24:05 -08:00 committed by GitHub
parent cd44e33a7e
commit 7596d905ab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 81 additions and 11 deletions

View file

@ -4,7 +4,7 @@
{title} {title}
background="var(--main-bg)" background="var(--main-bg)"
> >
<div class="emoji-container" {style} > <div class="emoji-container" {style} ref:container >
{#if loaded} {#if loaded}
<emoji-mart props-json={emojiMartPropsJson} ></emoji-mart> <emoji-mart props-json={emojiMartPropsJson} ></emoji-mart>
{:elseif error} {:elseif error}
@ -37,6 +37,30 @@
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: center center; 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> </style>
<script> <script>
import ModalDialog from './ModalDialog.html' import ModalDialog from './ModalDialog.html'
@ -50,6 +74,21 @@
import { on } from '../../../_utils/eventBus' import { on } from '../../../_utils/eventBus'
import { createEmojiMartPicker } from '../../../_react/createEmojiMartPicker' 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 { export default {
async oncreate () { async oncreate () {
onCreateDialog.call(this) onCreateDialog.call(this)
@ -60,6 +99,16 @@
define({ 'emoji-mart': Picker }) define({ 'emoji-mart': Picker })
} }
this.set({ loaded: true }) 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) { } catch (error) {
this.set({ error }) // should never happen, but you never know this.set({ error }) // should never happen, but you never know
} }
@ -81,16 +130,25 @@
min-height: ${$isSmallMobileSize ? 300 : 400}px; min-height: ${$isSmallMobileSize ? 300 : 400}px;
`), `),
emojiMartPropsJson: ({ emojiMartProps }) => JSON.stringify(emojiMartProps), emojiMartPropsJson: ({ emojiMartProps }) => JSON.stringify(emojiMartProps),
emojiMartProps: ({ perLine, custom, showPreview }) => ({ emojiMartProps: ({ perLine, custom }) => ({
perLine, perLine,
custom, custom,
showPreview,
color: 'var(--nav-bg)', color: 'var(--nav-bg)',
emoji: 'sailboat', emoji: 'sailboat',
title: 'Emoji' title: 'Emoji',
include: categoriesSort,
showPreview: true,
autoFocus: true
}), }),
showPreview: ({ $isSmallMobileSize }) => !$isSmallMobileSize, perLine: ({ $isSmallMobileSize, $isTinyMobileSize, $isMobileSize }) => (
perLine: ({ $isSmallMobileSize }) => $isSmallMobileSize ? 7 : 9, $isTinyMobileSize
? 7
: $isSmallMobileSize
? 8
: $isMobileSize
? 9
: 10
),
custom: ({ $currentCustomEmoji, $autoplayGifs }) => { custom: ({ $currentCustomEmoji, $autoplayGifs }) => {
if (!$currentCustomEmoji) { if (!$currentCustomEmoji) {
return [] return []

View file

@ -123,6 +123,17 @@
:global(body.modal-open) { :global(body.modal-open) {
overflow-y: hidden; 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> </style>
<script> <script>
import { A11yDialog } from '../../../_thirdparty/a11y-dialog/a11y-dialog' import { A11yDialog } from '../../../_thirdparty/a11y-dialog/a11y-dialog'

View file

@ -13,8 +13,8 @@ function onEmojiSelected (emoji) {
export default function createEmojiMartPickerFromData (data) { export default function createEmojiMartPickerFromData (data) {
return props => React.createElement(NimblePicker, Object.assign({ return props => React.createElement(NimblePicker, Object.assign({
set: 'all', set: 'twitter', // same as Mastodon frontend
data, data, // same as Mastodon frontend
native: true, native: true,
onSelect: onEmojiSelected onSelect: onEmojiSelected
}, props)) }, props))

View file

@ -7,8 +7,9 @@ export function resizeObservers (store) {
const recalculateIsMobileSize = () => { const recalculateIsMobileSize = () => {
store.set({ store.set({
isMobileSize: window.matchMedia('(max-width: 767px)').matches, isMobileSize: window.matchMedia('(max-width: 767px)').matches, // e.g. iPhone Plus
isSmallMobileSize: window.matchMedia('(max-width: 479px)').matches isSmallMobileSize: window.matchMedia('(max-width: 479px)').matches, // e.g. Galaxy S5
isTinyMobileSize: window.matchMedia('(max-width: 320px)').matches // e.g. iPhone 4
}) })
} }