refs #1281 Add emoji picker on reaction button

This commit is contained in:
AkiraFukushima 2020-04-22 22:23:00 +09:00
parent 5de8221bf1
commit f5dfd2474a
1 changed files with 62 additions and 24 deletions

View File

@ -103,7 +103,7 @@
<bdi v-html="username(message.account)"></bdi> <bdi v-html="username(message.account)"></bdi>
</span> </span>
</div> </div>
<div class="tool-box"> <div class="tool-box" v-click-outside="hideEmojiPicker">
<el-button type="text" @click="openReply()" class="reply" :title="$t('cards.toot.reply')" :aria-label="$t('cards.toot.reply')"> <el-button type="text" @click="openReply()" class="reply" :title="$t('cards.toot.reply')" :aria-label="$t('cards.toot.reply')">
<icon name="reply" scale="0.9"></icon> <icon name="reply" scale="0.9"></icon>
</el-button> </el-button>
@ -137,6 +137,21 @@
<span class="count"> <span class="count">
{{ favouritesCount }} {{ favouritesCount }}
</span> </span>
<el-button class="emoji" type="text" @click="toggleEmojiPicker">
<icon name="regular/smile" scale="0.9"></icon>
</el-button>
<div v-if="openEmojiPicker" class="emoji-picker">
<picker
set="emojione"
:autoFocus="true"
@select="selectEmoji"
:sheetSize="32"
:perLine="7"
:emojiSize="24"
:showPreview="false"
:emojiTooltip="true"
/>
</div>
<el-button class="pinned" type="text" :title="$t('cards.toot.pinned')" :aria-label="$t('cards.toot.pinned')" v-show="pinned"> <el-button class="pinned" type="text" :title="$t('cards.toot.pinned')" :aria-label="$t('cards.toot.pinned')" v-show="pinned">
<icon name="thumbtack" scale="0.9"></icon> <icon name="thumbtack" scale="0.9"></icon>
</el-button> </el-button>
@ -184,6 +199,8 @@
<script> <script>
import moment from 'moment' import moment from 'moment'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import { Picker } from 'emoji-mart-vue'
import ClickOutside from 'vue-click-outside'
import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser' import { findAccount, findLink, findTag } from '~/src/renderer/utils/tootParser'
import DisplayStyle from '~/src/constants/displayStyle' import DisplayStyle from '~/src/constants/displayStyle'
import TimeFormat from '~/src/constants/timeFormat' import TimeFormat from '~/src/constants/timeFormat'
@ -194,9 +211,13 @@ import { setInterval, clearInterval } from 'timers'
export default { export default {
name: 'toot', name: 'toot',
directives: {
ClickOutside
},
components: { components: {
FailoverImg, FailoverImg,
Poll Poll,
Picker
}, },
data() { data() {
return { return {
@ -204,7 +225,8 @@ export default {
showAttachments: this.$store.state.App.ignoreNFSW, showAttachments: this.$store.state.App.ignoreNFSW,
hideAllAttachments: this.$store.state.App.hideAllAttachments, hideAllAttachments: this.$store.state.App.hideAllAttachments,
now: Date.now(), now: Date.now(),
pollResponse: null pollResponse: null,
openEmojiPicker: false
} }
}, },
props: { props: {
@ -239,74 +261,74 @@ export default {
timeFormat: state => state.timeFormat, timeFormat: state => state.timeFormat,
language: state => state.language language: state => state.language
}), }),
shortcutEnabled: function() { shortcutEnabled: function () {
return this.focused && !this.overlaid return this.focused && !this.overlaid && !this.openEmojiPicker
}, },
timestamp: function() { timestamp: function () {
return this.parseDatetime(this.originalMessage.created_at, this.now) return this.parseDatetime(this.originalMessage.created_at, this.now)
}, },
readableTimestamp: function() { readableTimestamp: function () {
moment.locale(this.language) moment.locale(this.language)
return moment(this.originalMessage.created_at).format('LLLL') return moment(this.originalMessage.created_at).format('LLLL')
}, },
originalMessage: function() { originalMessage: function () {
if (this.message.reblog !== null) { if (this.message.reblog !== null) {
return this.message.reblog return this.message.reblog
} else { } else {
return this.message return this.message
} }
}, },
mediaAttachments: function() { mediaAttachments: function () {
return this.originalMessage.media_attachments return this.originalMessage.media_attachments
}, },
reblogsCount: function() { reblogsCount: function () {
if (this.originalMessage.reblogs_count > 0) { if (this.originalMessage.reblogs_count > 0) {
return this.originalMessage.reblogs_count return this.originalMessage.reblogs_count
} }
return '' return ''
}, },
favouritesCount: function() { favouritesCount: function () {
if (this.originalMessage.favourites_count > 0) { if (this.originalMessage.favourites_count > 0) {
return this.originalMessage.favourites_count return this.originalMessage.favourites_count
} }
return '' return ''
}, },
isMyMessage: function() { isMyMessage: function () {
return this.$store.state.TimelineSpace.account.accountId === this.originalMessage.account.id return this.$store.state.TimelineSpace.account.accountId === this.originalMessage.account.id
}, },
application: function() { application: function () {
let msg = this.originalMessage let msg = this.originalMessage
if (msg.application !== undefined && msg.application !== null) { if (msg.application !== undefined && msg.application !== null) {
return msg.application.name return msg.application.name
} }
return null return null
}, },
spoilered: function() { spoilered: function () {
return this.originalMessage.spoiler_text.length > 0 return this.originalMessage.spoiler_text.length > 0
}, },
isShowContent: function() { isShowContent: function () {
return !this.spoilered || this.showContent return !this.spoilered || this.showContent
}, },
poll: function() { poll: function () {
if (this.pollResponse) { if (this.pollResponse) {
return this.pollResponse return this.pollResponse
} else { } else {
return this.originalMessage.poll return this.originalMessage.poll
} }
}, },
sensitive: function() { sensitive: function () {
return (this.hideAllAttachments || this.originalMessage.sensitive) && this.mediaAttachments.length > 0 return (this.hideAllAttachments || this.originalMessage.sensitive) && this.mediaAttachments.length > 0
}, },
isShowAttachments: function() { isShowAttachments: function () {
return !this.sensitive || this.showAttachments return !this.sensitive || this.showAttachments
}, },
filtered: function() { filtered: function () {
return this.filter.length > 0 && this.originalMessage.content.search(this.filter) >= 0 return this.filter.length > 0 && this.originalMessage.content.search(this.filter) >= 0
}, },
locked: function() { locked: function () {
return this.message.visibility === 'private' return this.message.visibility === 'private'
}, },
directed: function() { directed: function () {
return this.message.visibility === 'direct' return this.message.visibility === 'direct'
} }
}, },
@ -322,13 +344,13 @@ export default {
clearInterval(this.updateInterval) clearInterval(this.updateInterval)
}, },
watch: { watch: {
focused: function(newState, oldState) { focused: function (newState, oldState) {
if (newState) { if (newState) {
this.$nextTick(function() { this.$nextTick(function () {
this.$refs.status.focus() this.$refs.status.focus()
}) })
} else if (oldState && !newState) { } else if (oldState && !newState) {
this.$nextTick(function() { this.$nextTick(function () {
this.$refs.status.blur() this.$refs.status.blur()
}) })
} }
@ -581,6 +603,15 @@ export default {
async refresh(id) { async refresh(id) {
const res = await this.$store.dispatch('organisms/Toot/refresh', id) const res = await this.$store.dispatch('organisms/Toot/refresh', id)
this.pollResponse = res this.pollResponse = res
},
toggleEmojiPicker() {
this.openEmojiPicker = !this.openEmojiPicker
},
hideEmojiPicker() {
this.openEmojiPicker = false
},
selectEmoji(emoji) {
console.log(emoji)
} }
} }
} }
@ -593,6 +624,7 @@ export default {
.toot { .toot {
padding: 8px 0 0 16px; padding: 8px 0 0 16px;
position: relative;
.fa-icon { .fa-icon {
font-size: 0.9em; font-size: 0.9em;
@ -833,6 +865,12 @@ export default {
.action-pop-over { .action-pop-over {
color: #303133; color: #303133;
} }
.emoji-picker {
position: absolute;
margin-top: 4px;
z-index: 10;
}
} }
.filtered { .filtered {