From b10b92a876eb185a88e751d028e69063c9117298 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson <shpuld@shpposter.club> Date: Tue, 14 Jan 2020 10:06:14 +0200 Subject: [PATCH] clean up code, fix prediction bug --- .../emoji_reactions/emoji_reactions.js | 30 +++++++++++ .../emoji_reactions/emoji_reactions.vue | 51 +++++++++++++++++++ src/components/react_button/react_button.js | 5 +- src/components/react_button/react_button.vue | 46 +++++++++-------- src/components/status/status.js | 23 ++------- src/components/status/status.vue | 47 ++--------------- src/modules/statuses.js | 9 ++-- 7 files changed, 122 insertions(+), 89 deletions(-) create mode 100644 src/components/emoji_reactions/emoji_reactions.js create mode 100644 src/components/emoji_reactions/emoji_reactions.vue diff --git a/src/components/emoji_reactions/emoji_reactions.js b/src/components/emoji_reactions/emoji_reactions.js new file mode 100644 index 00000000..e81e6e25 --- /dev/null +++ b/src/components/emoji_reactions/emoji_reactions.js @@ -0,0 +1,30 @@ + +const EmojiReactions = { + name: 'EmojiReactions', + props: ['status'], + computed: { + emojiReactions () { + return this.status.emojiReactions + } + }, + methods: { + reactedWith (emoji) { + return this.status.reactedWithEmoji.includes(emoji) + }, + reactWith (emoji) { + this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji }) + }, + unreact (emoji) { + this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji }) + }, + emojiOnClick (emoji, event) { + if (this.reactedWith(emoji)) { + this.unreact(emoji) + } else { + this.reactWith(emoji) + } + } + } +} + +export default EmojiReactions diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue new file mode 100644 index 00000000..d83f60b6 --- /dev/null +++ b/src/components/emoji_reactions/emoji_reactions.vue @@ -0,0 +1,51 @@ +<template> + <div class="emoji-reactions"> + <button + v-for="(users, emoji) in emojiReactions" + :key="emoji" + class="emoji-reaction btn btn-default" + :class="{ 'picked-reaction': reactedWith(emoji) }" + @click="emojiOnClick(emoji, $event)" + > + <span v-if="users">{{ users.length }}</span> + <span>{{ emoji }}</span> + </button> + </div> +</template> + +<script src="./emoji_reactions.js" ></script> +<style lang="scss"> +@import '../../_variables.scss'; + +.emoji-reactions { + display: flex; + margin-top: 0.25em; + flex-wrap: wrap; +} + +.emoji-reaction { + padding: 0 0.5em; + margin-right: 0.5em; + margin-top: 0.5em; + display: flex; + align-items: center; + justify-content: center; + box-sizing: border-box; + :first-child { + margin-right: 0.25em; + } + :last-child { + width: 1.5em; + } + &:focus { + outline: none; + } +} + +.picked-reaction { + border: 1px solid var(--link, $fallback--link); + margin-left: -1px; // offset the border, can't use inset shadows either + margin-right: calc(0.5em - 1px); +} + +</style> diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js index 76a49305..d1a179bc 100644 --- a/src/components/react_button/react_button.js +++ b/src/components/react_button/react_button.js @@ -15,8 +15,9 @@ const ReactButton = { } }, methods: { - toggleReactionSelect () { - this.showTooltip = !this.showTooltip + openReactionSelect () { + this.showTooltip = true + this.filterWord = '' }, closeReactionSelect () { this.showTooltip = false diff --git a/src/components/react_button/react_button.vue b/src/components/react_button/react_button.vue index f7015316..ae975dee 100644 --- a/src/components/react_button/react_button.vue +++ b/src/components/react_button/react_button.vue @@ -9,13 +9,16 @@ > <div slot="popover"> <div class="reaction-picker-filter"> - <input v-model="filterWord" placeholder="Search..."> + <input + v-model="filterWord" + :placeholder="$t('emoji.search_emoji')" + > </div> <div class="reaction-picker"> <span v-for="emoji in commonEmojis" :key="emoji" - class="emoji-reaction-button" + class="emoji-button" @click="addReaction($event, emoji)" > {{ emoji }} @@ -24,7 +27,7 @@ <span v-for="(emoji, key) in emojis" :key="key" - class="emoji-reaction-button" + class="emoji-button" @click="addReaction($event, emoji.replacement)" > {{ emoji.replacement }} @@ -34,11 +37,11 @@ </div> <div v-if="loggedIn" - @click.prevent="toggleReactionSelect" + @click.prevent="openReactionSelect" > <i :class="classes" - class="button-icon favorite-button fav-active" + class="button-icon add-reaction-button" :title="$t('tool_tip.add_reaction')" /> <span v-if="!mergedConfig.hidePostStats && status.fave_num > 0">{{ status.fave_num }}</span> @@ -58,7 +61,7 @@ .reaction-picker-divider { height: 1px; width: 100%; - margin: 0.4em; + margin: 0.5em; background-color: var(--border, $fallback--border); } @@ -82,26 +85,27 @@ // Autoprefixed seem to ignore this one, and also syntax is different -webkit-mask-composite: xor; mask-composite: exclude; -} -.emoji-reaction-button { - flex-basis: 20%; - line-height: 1.5em; - align-content: center; -} + .emoji-button { + cursor: pointer; -.fav-active { - cursor: pointer; - animation-duration: 0.6s; + flex-basis: 20%; + line-height: 1.5em; + align-content: center; - &:hover { - color: $fallback--cOrange; - color: var(--cOrange, $fallback--cOrange); + &:hover { + transform: scale(1.25); + } } } -.favorite-button.icon-star { - color: $fallback--cOrange; - color: var(--cOrange, $fallback--cOrange); +.add-reaction-button { + cursor: pointer; + + &:hover { + color: $fallback--text; + color: var(--text, $fallback--text); + } } + </style> diff --git a/src/components/status/status.js b/src/components/status/status.js index 18617938..81b57667 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -12,6 +12,7 @@ import LinkPreview from '../link-preview/link-preview.vue' import AvatarList from '../avatar_list/avatar_list.vue' import Timeago from '../timeago/timeago.vue' import StatusPopover from '../status_popover/status_popover.vue' +import EmojiReactions from '../emoji_reactions/emoji_reactions.vue' import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' import fileType from 'src/services/file_type/file_type.service' import { processHtml } from 'src/services/tiny_post_html_processor/tiny_post_html_processor.service.js' @@ -311,9 +312,6 @@ const Status = { hidePostStats () { return this.mergedConfig.hidePostStats }, - emojiReactions () { - return this.status.emojiReactions - }, ...mapGetters(['mergedConfig']), ...mapState({ betterShadow: state => state.interface.browserSupport.cssFilter, @@ -334,7 +332,8 @@ const Status = { LinkPreview, AvatarList, Timeago, - StatusPopover + StatusPopover, + EmojiReactions }, methods: { visibilityIcon (visibility) { @@ -418,22 +417,6 @@ const Status = { setMedia () { const attachments = this.attachmentSize === 'hide' ? this.status.attachments : this.galleryAttachments return () => this.$store.dispatch('setMedia', attachments) - }, - reactedWith (emoji) { - return this.status.reactedWithEmoji.includes(emoji) - }, - reactWith (emoji) { - this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji }) - }, - unreact (emoji) { - this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji }) - }, - emojiOnClick (emoji, event) { - if (this.reactedWith(emoji)) { - this.unreact(emoji) - } else { - this.reactWith(emoji) - } } }, watch: { diff --git a/src/components/status/status.vue b/src/components/status/status.vue index 4ea1b74b..87e8b5da 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -354,18 +354,10 @@ </div> </transition> - <div v-if="isFocused" class="emoji-reactions"> - <button - v-for="(users, emoji) in emojiReactions" - :key="emoji" - class="emoji-reaction btn btn-default" - :class="{ 'picked-reaction': reactedWith(emoji) }" - @click="emojiOnClick(emoji, $event)" - > - <span v-if="users">{{ users.length }}</span> - <span>{{ emoji }}</span> - </button> - </div> + <EmojiReactions + v-if="isFocused" + :status="status" + /> <div v-if="!noHeading && !isPreview" @@ -789,37 +781,6 @@ $status-margin: 0.75em; } } -.emoji-reactions { - display: flex; - margin-top: 0.25em; - flex-wrap: wrap; -} - -.emoji-reaction { - padding: 0 0.5em; - margin-right: 0.5em; - margin-top: 0.5em; - display: flex; - align-items: center; - justify-content: center; - box-sizing: border-box; - :first-child { - margin-right: 0.25em; - } - :last-child { - width: 1.5em; - } - &:focus { - outline: none; - } -} - -.picked-reaction { - border: 1px solid var(--link, $fallback--link); - margin-left: -1px; // offset the border, can't use inset shadows either - margin-right: calc(0.5em - 1px); -} - .button-icon.icon-reply { &:not(.button-icon-disabled):hover, &.button-icon-active { diff --git a/src/modules/statuses.js b/src/modules/statuses.js index ae6f6853..dbae9d38 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -537,7 +537,10 @@ export const mutations = { addEmojiReactions (state, { id, emojiReactions, currentUser }) { const status = state.allStatusesObject[id] set(status, 'emojiReactions', emojiReactions) - const reactedWithEmoji = flow(keys, filter(reaction => find(reaction, { id: currentUser.id })))(emojiReactions) + const reactedWithEmoji = flow( + keys, + filter(reaction => find(reaction, { id: currentUser.id })) + )(emojiReactions) set(status, 'reactedWithEmoji', reactedWithEmoji) }, addOwnReaction (state, { id, emoji, currentUser }) { @@ -547,7 +550,7 @@ export const mutations = { const hasSelfAlready = !!find(listOfUsers, { id: currentUser.id }) if (!hasSelfAlready) { set(status.emojiReactions, emoji, listOfUsers.concat([{ id: currentUser.id }])) - set(status, 'reactedWithEmoji', emoji) + set(status, 'reactedWithEmoji', [...status.reactedWithEmoji, emoji]) } }, removeOwnReaction (state, { id, emoji, currentUser }) { @@ -557,7 +560,7 @@ export const mutations = { if (hasSelfAlready) { const newUsers = filter(listOfUsers, user => user.id !== currentUser.id) set(status.emojiReactions, emoji, newUsers) - set(status, 'reactedWith', emoji) + set(status, 'reactedWithEmoji', status.reactedWithEmoji.filter(e => e !== emoji)) } }, updateStatusWithPoll (state, { id, poll }) {