Merge pull request #516 from h3poteto/iss-480

refs #480 Parse emoji and show emoji in toot
This commit is contained in:
AkiraFukushima 2018-08-19 10:35:50 +09:00 committed by GitHub
commit 7dd4817471
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 7 deletions

View File

@ -20,7 +20,7 @@
</div>
<div class="content-wrapper">
<div class="spoiler" v-show="spoilered(message)">
{{ originalMessage(message).spoiler_text }}
<span v-html="spoilerText(message)"></span>
<el-button v-show="!isShowContent(message)" type="text" @click="showContent = true">
{{ $t('cards.toot.show_more') }}
</el-button>
@ -28,7 +28,7 @@
{{ $t('cards.toot.hide')}}
</el-button>
</div>
<div class="content" v-show="isShowContent(message)" v-html="originalMessage(message).content" @click.capture.prevent="tootClick"></div>
<div class="content" v-show="isShowContent(message)" v-html="status(message)" @click.capture.prevent="tootClick"></div>
</div>
<div class="attachments">
<el-button v-show="sensitive(message) && !isShowAttachments(message)" class="show-sensitive" type="info" @click="showAttachments = true">
@ -110,6 +110,7 @@ import { shell, clipboard } from 'electron'
import { mapState } from 'vuex'
import { findAccount, findLink, isTag } from '../../../utils/link'
import DisplayStyle from '~/src/constants/displayStyle'
import emojify from '~/src/renderer/utils/emojify'
export default {
name: 'toot',
@ -339,6 +340,14 @@ export default {
},
locked (message) {
return message.visibility === 'private' || message.visibility === 'direct'
},
status (message) {
const original = this.originalMessage(message)
return emojify(original.content, original.emojis)
},
spoilerText (message) {
const original = this.originalMessage(message)
return emojify(original.spoiler_text, original.emojis)
}
}
}
@ -395,7 +404,7 @@ export default {
}
}
.content-wrapper {
.content-wrapper /deep/ {
font-size: var(--base-font-size);
color: var(--theme-primary-color);
@ -403,6 +412,11 @@ export default {
margin: 4px 0 8px;
word-wrap: break-word;
}
.emojione {
width: 20px;
height: 20px;
}
}
.attachments {

View File

@ -4,8 +4,8 @@
<div v-shortkey="{linux: ['ctrl', 'r'], mac: ['meta', 'r']}" @shortkey="reload()">
</div>
<transition-group name="timeline" tag="div">
<div class="home-timeline" v-for="(message, index) in timeline" v-bind:key="index">
<toot :message="message" :filter="filter" :key="message.id" v-on:update="updateToot" v-on:delete="deleteToot"></toot>
<div class="home-timeline" v-for="message in timeline" :key="message.id">
<toot :message="message" :filter="filter" v-on:update="updateToot" v-on:delete="deleteToot"></toot>
</div>
</transition-group>
<div class="loading-card" v-loading="lazyLoading" :element-loading-background="backgroundColor">

View File

@ -4,7 +4,7 @@
<div v-shortkey="{linux: ['ctrl', 'r'], mac: ['meta', 'r']}" @shortkey="reload()">
</div>
<transition-group name="timeline" tag="div">
<div class="local-timeline" v-for="message in timeline" v-bind:key="message.id">
<div class="local-timeline" v-for="message in timeline" :key="message.id">
<toot :message="message" :filter="filter" v-on:update="updateToot" v-on:delete="deleteToot"></toot>
</div>
</transition-group>

View File

@ -4,7 +4,7 @@
<div v-shortkey="{linux: ['ctrl', 'r'], mac: ['meta', 'r']}" @shortkey="reload()">
</div>
<transition-group name="timeline" tag="div">
<div class="public-timeline" v-for="message in timeline" v-bind:key="message.id">
<div class="public-timeline" v-for="message in timeline" :key="message.id">
<toot :message="message" :filter="filter" v-on:update="updateToot" v-on:delete="deleteToot"></toot>
</div>
</transition-group>

View File

@ -0,0 +1,14 @@
const emojify = (str, customEmoji = []) => {
let result = str
customEmoji.map((emoji) => {
const reg = new RegExp(`:${emoji.shortcode}:`, 'g')
const match = result.match(reg)
if (!match) return emoji
const replaceTag = `<img draggable="false" class="emojione" alt="${emoji.shortcode}" title="${emoji.shortcode}" src="${emoji.url}" />`
result = result.replace(reg, replaceTag)
return emoji
})
return result
}
export default emojify

View File

@ -0,0 +1,59 @@
import assert from 'assert'
import emojify from '../../src/renderer/utils/emojify'
describe('emojify', () => {
const emoji = [
{
shortcode: 'python',
url: 'https://example.com/python'
},
{
shortcode: 'nodejs',
url: 'https://example.com/nodejs'
},
{
shortcode: 'slack',
url: 'https://example.com/slack'
}
]
context('Does not contain shortcode', () => {
const str = 'I have a pen.'
it('should not change', () => {
const result = emojify(str, emoji)
assert.strictEqual(
result,
str
)
})
})
context('Contain a shortcode', () => {
const str = 'I like :python:'
it('should replace', () => {
const result = emojify(str, emoji)
assert.strictEqual(
result,
'I like <img draggable="false" class="emojione" alt="python" title="python" src="https://example.com/python" />'
)
})
})
context('Contain some shortcodes', () => {
const str = 'I like :python: , :nodejs: and :slack:'
it('should replace', () => {
const result = emojify(str, emoji)
assert.strictEqual(
result,
'I like <img draggable="false" class="emojione" alt="python" title="python" src="https://example.com/python" /> , <img draggable="false" class="emojione" alt="nodejs" title="nodejs" src="https://example.com/nodejs" /> and <img draggable="false" class="emojione" alt="slack" title="slack" src="https://example.com/slack" />'
)
})
})
context('Contain same shortcodes', () => {
const str = 'I like :python: , I love :python:'
it('should replace', () => {
const result = emojify(str, emoji)
assert.strictEqual(
result,
'I like <img draggable="false" class="emojione" alt="python" title="python" src="https://example.com/python" /> , I love <img draggable="false" class="emojione" alt="python" title="python" src="https://example.com/python" />'
)
})
})
})