diff options
| author | HJ <30-hj@users.noreply.git.pleroma.social> | 2020-02-11 23:09:15 +0000 |
|---|---|---|
| committer | HJ <30-hj@users.noreply.git.pleroma.social> | 2020-02-11 23:09:15 +0000 |
| commit | 84ebae8ed36390f62ccda653d4fb9d8aad1482a2 (patch) | |
| tree | 70fb486e4b31b029c8dbcb89f87acf154275f905 /src/components/emoji_reactions | |
| parent | 60446c56a5c8d4b4d669fbd4803e77ce686daac9 (diff) | |
| parent | 96dc297babd5797b9307af8676719c2eb8cd80e2 (diff) | |
Merge branch 'develop' into 'themes-accent'
# Conflicts:
# src/components/emoji_reactions/emoji_reactions.vue
Diffstat (limited to 'src/components/emoji_reactions')
| -rw-r--r-- | src/components/emoji_reactions/emoji_reactions.js | 48 | ||||
| -rw-r--r-- | src/components/emoji_reactions/emoji_reactions.vue | 103 |
2 files changed, 139 insertions, 12 deletions
diff --git a/src/components/emoji_reactions/emoji_reactions.js b/src/components/emoji_reactions/emoji_reactions.js index 95d52cb6..b799ac9a 100644 --- a/src/components/emoji_reactions/emoji_reactions.js +++ b/src/components/emoji_reactions/emoji_reactions.js @@ -1,17 +1,55 @@ +import UserAvatar from '../user_avatar/user_avatar.vue' + +const EMOJI_REACTION_COUNT_CUTOFF = 12 const EmojiReactions = { name: 'EmojiReactions', + components: { + UserAvatar + }, props: ['status'], + data: () => ({ + showAll: false, + popperOptions: { + modifiers: { + preventOverflow: { padding: { top: 50 }, boundariesElement: 'viewport' } + } + } + }), computed: { + tooManyReactions () { + return this.status.emoji_reactions.length > EMOJI_REACTION_COUNT_CUTOFF + }, emojiReactions () { - return this.status.emoji_reactions + return this.showAll + ? this.status.emoji_reactions + : this.status.emoji_reactions.slice(0, EMOJI_REACTION_COUNT_CUTOFF) + }, + showMoreString () { + return `+${this.status.emoji_reactions.length - EMOJI_REACTION_COUNT_CUTOFF}` + }, + accountsForEmoji () { + return this.status.emoji_reactions.reduce((acc, reaction) => { + acc[reaction.name] = reaction.accounts || [] + return acc + }, {}) + }, + loggedIn () { + return !!this.$store.state.users.currentUser } }, methods: { + toggleShowAll () { + this.showAll = !this.showAll + }, reactedWith (emoji) { - const user = this.$store.state.users.currentUser - const reaction = this.status.emoji_reactions.find(r => r.emoji === emoji) - return reaction.accounts && reaction.accounts.find(u => u.id === user.id) + return this.status.emoji_reactions.find(r => r.name === emoji).me + }, + fetchEmojiReactionsByIfMissing () { + const hasNoAccounts = this.status.emoji_reactions.find(r => !r.accounts) + if (hasNoAccounts) { + this.$store.dispatch('fetchEmojiReactionsBy', this.status.id) + } }, reactWith (emoji) { this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji }) @@ -20,6 +58,8 @@ const EmojiReactions = { this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji }) }, emojiOnClick (emoji, event) { + if (!this.loggedIn) return + if (this.reactedWith(emoji)) { this.unreact(emoji) } else { diff --git a/src/components/emoji_reactions/emoji_reactions.vue b/src/components/emoji_reactions/emoji_reactions.vue index f5d2e79a..290b25b3 100644 --- a/src/components/emoji_reactions/emoji_reactions.vue +++ b/src/components/emoji_reactions/emoji_reactions.vue @@ -1,16 +1,58 @@ <template> <div class="emoji-reactions"> - <button + <v-popover v-for="(reaction) in emojiReactions" - :key="reaction.emoji" - class="emoji-reaction btn btn-default" - :class="{ 'toggled': reactedWith(reaction.emoji) }" - @click="emojiOnClick(reaction.emoji, $event)" + :key="reaction.name" + :popper-options="popperOptions" + trigger="hover" + placement="top" > - <span class="reaction-emoji">{{ reaction.emoji }}</span> - <span>{{ reaction.count }}</span> - </button> + + <div + slot="popover" + class="reacted-users" + > + <div v-if="accountsForEmoji[reaction.name].length"> + <div + v-for="(account) in accountsForEmoji[reaction.name]" + :key="account.id" + class="reacted-user" + > + <UserAvatar + :user="account" + class="avatar-small" + :compact="true" + /> + <div class="reacted-user-names"> + <span class="reacted-user-name" v-html="account.name_html" /> + <span class="reacted-user-screen-name">{{ account.screen_name }}</span> + </div> + </div> + </div> + <div v-else> + <i class="icon-spin4 animate-spin" /> + </div> + </div> + <button + class="emoji-reaction btn btn-default" + :class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }" + @click="emojiOnClick(reaction.name, $event)" + @mouseenter="fetchEmojiReactionsByIfMissing()" + > + <span class="reaction-emoji">{{ reaction.name }}</span> + <span>{{ reaction.count }}</span> + </button> + </v-popover> + <a + v-if="tooManyReactions" + @click="toggleShowAll" + class="emoji-reaction-expand faint" + href='javascript:void(0)' + > + {{ showAll ? $t('general.show_less') : showMoreString }} + </a> </div> + </template> <script src="./emoji_reactions.js" ></script> @@ -23,6 +65,31 @@ flex-wrap: wrap; } +.reacted-users { + padding: 0.5em; +} + +.reacted-user { + padding: 0.25em; + display: flex; + flex-direction: row; + + .reacted-user-names { + display: flex; + flex-direction: column; + margin-left: 0.5em; + + img { + width: 1em; + height: 1em; + } + } + + .reacted-user-screen-name { + font-size: 9px; + } +} + .emoji-reaction { padding: 0 0.5em; margin-right: 0.5em; @@ -38,6 +105,26 @@ &:focus { outline: none; } + + &.not-clickable { + cursor: default; + &:hover { + box-shadow: $fallback--buttonShadow; + box-shadow: var(--buttonShadow); + } + } +} + +.emoji-reaction-expand { + padding: 0 0.5em; + margin-right: 0.5em; + margin-top: 0.5em; + display: flex; + align-items: center; + justify-content: center; + &:hover { + text-decoration: underline; + } } </style> |
