fix(emoji): make emoji picker more like Mastodon's (#842)
This commit is contained in:
parent
cd44e33a7e
commit
7596d905ab
|
@ -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 []
|
||||||
|
|
|
@ -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'
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue