Skip to content
Permalink
Browse files

feat: improve emoji support

This adds an emoji font (Noto Color Emoji, thanks @mixmix!) and revamps
the emoji rendering and suggestion systems to support a bunch of new emoji.
  • Loading branch information...
christianbundy committed Jun 13, 2019
1 parent 746caec commit 0a2ff1aab8747dadadb045bbbc50ea08f1d68ede
@@ -4,7 +4,6 @@
"abouts",
"backlinks",
"depnest",
"emojilib",
"flatpickr",
"msgs",
"paramap",
@@ -18,4 +17,4 @@
],
"standard.autoFixOnSave": true,
"editor.tabSize": 2
}
}
@@ -130,6 +130,12 @@ module.exports = function (config) {
})
)

document.head.appendChild(
h('style', {
innerHTML: requireStyle('noto-color-emoji')
})
)

document.head.appendChild(
h('style', {
innerHTML: computed(api.settings.obs.get('patchwork.fontSize'), size => {
@@ -144,7 +150,7 @@ module.exports = function (config) {
h('style', {
innerHTML: computed(api.settings.obs.get('patchwork.fontFamily'), family => {
if (family) {
return 'body, button, input, select, textarea {font-family: ' + family + ';}'
return 'body, button, input, select, textarea { font-family: ' + family + ';}'
}
})
})

This file was deleted.

@@ -5,11 +5,11 @@ const nest = require('depnest')
var htmlEscape = require('html-escape')
var watch = require('mutant/watch')
const querystring = require('querystring')
const nodeEmoji = require('node-emoji')

exports.needs = nest({
'blob.sync.url': 'first',
'blob.obs.has': 'first',
'emoji.sync.url': 'first'
'blob.obs.has': 'first'
})

exports.gives = nest('message.html.markdown')
@@ -42,15 +42,15 @@ exports.create = function (api) {
return h('Markdown', {
classList,
hooks: [
LoadingBlobHook(api.blob.obs.has),
LargeEmojiHook()
LoadingBlobHook(api.blob.obs.has)
],
innerHTML: renderer.block(content.text, {
emoji: (emoji) => {
var url = emojiMentions[emoji]
? api.blob.sync.url(emojiMentions[emoji])
: api.emoji.sync.url(emoji)
return renderEmoji(emoji, url)
if (emojiMentions[emoji]) {
return renderEmoji(emoji, api.blob.sync.url(emojiMentions[emoji]))
} else {
return h('span.Emoji', nodeEmoji.get(emoji))
}
},
toUrl: (id) => {
var link = ref.parseLink(id)
@@ -75,6 +75,7 @@ exports.create = function (api) {

function renderEmoji (emoji, url) {
if (!url) return ':' + emoji + ':'

return `
<img
src="${htmlEscape(url)}"
@@ -108,18 +109,3 @@ function LoadingBlobHook (hasBlob) {
}
}
}

function LargeEmojiHook () {
return function (element) {
// do our best with a css selector
element.querySelectorAll('p > img.emoji:only-child').forEach(img => {
// unfortunately `only-child` doesn't take text nodes into account
// check to see if there is actually any text before or after before adding class
var before = img.previousSibling && img.previousSibling.textContent.trim()
var after = img.nextSibling && img.nextSibling.textContent.trim()
if (!before && !after) {
img.classList.add('-large')
}
})
}
}
@@ -1,13 +1,13 @@
var h = require('mutant/h')
var nest = require('depnest')
var when = require('mutant/when')
const emoji = require('node-emoji')

exports.needs = nest({
'sheet.display': 'first',
'message.html.render': 'first',
'intl.sync.i18n': 'first',
'intl.sync.i18n_n': 'first',
'emoji.sync.url': 'first'
'intl.sync.i18n_n': 'first'
})

exports.gives = nest('message.sheet.preview')
@@ -55,8 +55,8 @@ exports.create = function (api) {
],
footer: [
when(isPrivate,
h('img', { src: api.emoji.sync.url('closed_lock_with_key') }),
h('img', { src: api.emoji.sync.url('globe_with_meridians') })
h('span.Emoji', emoji.get('closed_lock_with_key')),
h('span.Emoji', emoji.get('globe_with_meridians'))
),
when(isPrivate,
h('div.info -private', [
@@ -1,13 +1,12 @@
const nest = require('depnest')
var emoji = require('emojilib')
var addSuggest = require('suggest-box')
var resolve = require('mutant/resolve')
var h = require('hyperscript')
const emoji = require('node-emoji')

exports.needs = nest({
'profile.async.suggest': 'first',
'channel.async.suggest': 'first',
'emoji.sync.names': 'first',
'emoji.sync.url': 'first'
'channel.async.suggest': 'first'
})

exports.gives = nest('suggest.hook')
@@ -29,24 +28,16 @@ exports.create = function (api) {
if (word[word.length - 1] === ':') {
word = word.slice(0, -1)
}
cb(null, suggestEmoji(word).slice(0, 100).map(function (emoji) {
cb(null, emoji.search(word).slice(0, 100).map(function (result) {
// result = { key: emoji}
return {
image: api.emoji.sync.url(emoji),
title: emoji,
subtitle: emoji,
value: ':' + emoji + ':'
title: h('span.Emoji', result.emoji),
subtitle: result.key,
value: `:${result.key}:`
}
}))
}
}, { cls: 'SuggestBox' })
}
})

function suggestEmoji (prefix) {
var availableEmoji = api.emoji.sync.names()
return emoji.ordered.filter(key => {
if (!availableEmoji.includes(key)) return false
return key.startsWith(prefix) || key.includes('_' + prefix) || emoji.lib[key].keywords.some(word => word.startsWith(prefix) || word.startsWith(':' + prefix))
})
}
}

Some generated files are not rendered by default. Learn more.

@@ -27,8 +27,6 @@
"electron-default-menu": "~1.0.1",
"electron-spellchecker": "^2.0.4",
"electron-window-state": "^5.0.3",
"emoji-named-characters": "^1.0.2",
"emojilib": "^2.4.0",
"escape-string-regexp": "^2.0.0",
"fix-path": "^2.1.0",
"flat": "^4.1.0",
@@ -48,6 +46,8 @@
"moment-timezone": "^0.5.23",
"mutant": "github:mmckegg/mutant#intersection-binding-viewport",
"mutant-pull-reduce": "^1.1.0",
"node-emoji": "^1.10.0",
"noto-color-emoji": "^1.0.1",
"patch-settings": "^1.1.2",
"pull-abortable": "^4.1.1",
"pull-cat": "^1.1.11",
@@ -1,11 +1,14 @@
html {
font-size: 12px
}

html, body {
margin: 0
font: caption
overflow: hidden
height: 100%
font-size: 12px
-webkit-user-select: none
}

body {
display: flex
flex-direction: column
@@ -42,9 +45,10 @@ a {
* {
box-sizing: border-box
}
input, textarea, keygen, select, button {
font-family: '.SFNSText-Regular', sans-serif
}
::-webkit-file-upload-button {
font-family: inherit
}

Emoji {
font-family: NotoColorEmoji
}
@@ -59,18 +59,6 @@ Markdown {
margin: 0
}
}
(img.emoji) {
width: 1.5em
height: 1.5em
align-content: center
margin-bottom: -0.3em

-large {
width: 3rem
height: 3rem
}
}

-fullCode {
(pre) {
max-height: none

0 comments on commit 0a2ff1a

Please sign in to comment.
You can’t perform that action at this time.