Merge branch 'custom_reacts' into stable (edwin squirty)

This commit is contained in:
Zero 2022-12-01 17:54:36 -05:00
commit 2745aabcb4
8 changed files with 92 additions and 105 deletions

View File

@ -1,9 +1,28 @@
@import '../../_variables.scss';
.Notification {
.emoji-picker {
min-width: 160%;
width: 150%;
overflow: hidden;
left: -70%;
max-width: 100%;
@media (min-width: 800px) and (max-width: 1300px) {
left: -50%;
min-width: 50%;
max-width: 130%;
}
@media (max-width: 800px) {
left: -10%;
min-width: 50%;
max-width: 130%;
}
}
}
.emoji-picker {
display: flex;
flex-direction: column;
position: absolute;
right: 0;
left: 0;
margin: 0 !important;

View File

@ -27,7 +27,11 @@ const EmojiReactions = {
},
accountsForEmoji () {
return this.status.emoji_reactions.reduce((acc, reaction) => {
acc[reaction.name] = reaction.accounts || []
if (reaction.url) {
acc[reaction.url] = reaction.accounts || []
} else {
acc[reaction.name] = reaction.accounts || []
}
return acc
}, {})
},
@ -42,6 +46,14 @@ const EmojiReactions = {
reactedWith (emoji) {
return this.status.emoji_reactions.find(r => r.name === emoji).me
},
isLocalReaction (emojiUrl) {
if (!emojiUrl) return true
const reacted = this.accountsForEmoji[emojiUrl]
if (reacted.length === 0) {
return true
}
return reacted[0].is_local
},
fetchEmojiReactionsByIfMissing () {
const hasNoAccounts = this.status.emoji_reactions.find(r => !r.accounts)
if (hasNoAccounts) {

View File

@ -2,17 +2,33 @@
<div class="emoji-reactions">
<UserListPopover
v-for="(reaction) in emojiReactions"
:key="reaction.name"
:users="accountsForEmoji[reaction.name]"
:key="reaction.url || reaction.name"
:users="accountsForEmoji[reaction.url || reaction.name]"
>
<button
class="emoji-reaction btn button-default"
:class="{ 'picked-reaction': reactedWith(reaction.name), 'not-clickable': !loggedIn }"
:disabled="!isLocalReaction(reaction.url)"
@click="emojiOnClick(reaction.name, $event)"
@mouseenter="fetchEmojiReactionsByIfMissing()"
>
<span class="reaction-emoji">{{ reaction.name }}</span>
<span>{{ reaction.count }}</span>
<span
v-if="reaction.url !== null"
>
<img
:src="reaction.url"
:title="reaction.name"
class="emoji"
height="32px"
>
{{ reaction.count }}
</span>
<span v-else>
<span class="reaction-emoji unicode-emoji">
{{ reaction.name }}
</span>
<span>{{ reaction.count }}</span>
</span>
</button>
</UserListPopover>
<a
@ -36,6 +52,10 @@
flex-wrap: wrap;
}
.unicode-emoji {
font-size: 185%;
}
.emoji-reaction {
padding: 0 0.5em;
margin-right: 0.5em;
@ -44,10 +64,6 @@
align-items: center;
justify-content: center;
box-sizing: border-box;
.reaction-emoji {
width: 1.25em;
margin-right: 0.25em;
}
&:focus {
outline: none;
}
@ -73,7 +89,7 @@
}
}
.picked-reaction {
.button-default.picked-reaction {
border: 1px solid var(--accent, $fallback--link);
margin-left: -1px; // offset the border, can't use inset shadows either
margin-right: calc(0.5em - 1px);

View File

@ -1,5 +1,12 @@
@import '../../_variables.scss';
.notification-reaction-emoji {
width: 40px;
display: inline-flex;
vertical-align: middle;
flex-direction: column;
}
// TODO Copypaste from Status, should unify it somehow
.Notification {
&.-muted {

View File

@ -102,7 +102,18 @@
<span v-if="notification.type === 'pleroma:emoji_reaction'">
<small>
<i18n path="notifications.reacted_with">
<span class="emoji-reaction-emoji">{{ notification.emoji }}</span>
<img
v-if="notification.emoji_url !== null"
class="notification-reaction-emoji"
:src="notification.emoji_url"
:name="notification.emoji"
>
<span
v-else
class="emoji-reaction-emoji"
>
{{ notification.emoji }}
</span>
</i18n>
</small>
</span>

View File

@ -1,5 +1,5 @@
import Checkbox from '../checkbox/checkbox.vue'
import Popover from '../popover/popover.vue'
import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faSmileBeam } from '@fortawesome/free-regular-svg-icons'
@ -9,26 +9,23 @@ const ReactButton = {
props: ['status'],
data () {
return {
filterWord: '',
keepReactOpen: false
filterWord: ''
}
},
components: {
Popover,
Checkbox
EmojiPicker
},
methods: {
addReaction (event, emoji, close, keepReactOpen) {
addReaction (event, close) {
const emoji = event.insertion
const existingReaction = this.status.emoji_reactions.find(r => r.name === emoji)
if (existingReaction && existingReaction.me) {
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
} else {
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
}
this.keepReactOpen = keepReactOpen
if (!keepReactOpen) {
close()
}
if (!event.keepOpen) { close() }
},
focusInput () {
this.$nextTick(() => {
@ -38,47 +35,6 @@ const ReactButton = {
}
},
computed: {
commonEmojis () {
return [
{ displayText: 'lying', replacement: '🤥' },
{ displayText: 'thinking', replacement: '🤔' },
{ displayText: 'zany', replacement: '🤪' },
{ displayText: 'cartwheeling', replacement: '🤸‍♂️' },
{ displayText: 'pills', replacement: '💊' },
{ displayText: 'writing', replacement: '✍️' },
{ displayText: 'pencil', replacement: '✏️' },
{ displayText: 'chart_up', replacement: '📈' },
{ displayText: 'chart_down', replacement: '📉' },
{ displayText: 'question', replacement: '❔' },
{ displayText: 'x', replacement: '❌' },
{ displayText: 'orangutan', replacement: '🦧' },
{ displayText: 'owl', replacement: '🦉' },
{ displayText: 'bottle', replacement: '🍼' },
{ displayText: 'crayon', replacement: '🖍️' },
{ displayText: 'blackula', replacement: '🧛🏿' },
{ displayText: 'wrench', replacement: '🔧' },
{ displayText: 'axe', replacement: '🪓' }
]
},
emojis () {
if (this.filterWord !== '') {
const filterWordLowercase = this.filterWord.toLowerCase()
let orderedEmojiList = []
for (const emoji of this.$store.state.instance.emoji) {
if (emoji.replacement === this.filterWord) return [emoji]
const indexOfFilterWord = emoji.displayText.toLowerCase().indexOf(filterWordLowercase)
if (indexOfFilterWord > -1) {
if (!Array.isArray(orderedEmojiList[indexOfFilterWord])) {
orderedEmojiList[indexOfFilterWord] = []
}
orderedEmojiList[indexOfFilterWord].push(emoji)
}
}
return orderedEmojiList.flat()
}
return this.$store.state.instance.emoji || []
},
mergedConfig () {
return this.$store.getters.mergedConfig
}

View File

@ -9,40 +9,10 @@
@show="focusInput"
>
<template v-slot:content="{close}">
<div class="reaction-picker-filter">
<input
v-model="filterWord"
size="1"
:placeholder="$t('emoji.search_emoji')"
>
</div>
<div class="keep-open">
<Checkbox v-model="keepReactOpen">
{{ $t('emoji.keep_open') }}
</Checkbox>
</div>
<div class="reaction-picker">
<span
v-for="emoji in commonEmojis"
:key="emoji.replacement"
class="emoji-button"
:title="emoji.displayText"
@click="addReaction($event, emoji.replacement, close, keepReactOpen)"
>
{{ emoji.replacement }}
</span>
<div class="reaction-picker-divider" />
<span
v-for="(emoji, key) in emojis"
:key="key"
class="emoji-button"
:title="emoji.displayText"
@click="addReaction($event, emoji.replacement, close, keepReactOpen)"
>
{{ emoji.replacement }}
</span>
<div class="reaction-bottom-fader" />
</div>
<EmojiPicker
:enableStickerPicker="false"
@emoji="addReaction($event, close)"
/>
</template>
<template v-slot:trigger>
<button
@ -63,6 +33,10 @@
<style lang="scss">
@import '../../_variables.scss';
.custom-reaction {
width: 30px !important;
}
.ReactButton {
.reaction-picker-filter {
padding: 0.5em;
@ -129,15 +103,6 @@
color: var(--text, $fallback--text);
}
}
.keep-open,
.too-many-emoji {
padding: 7px;
line-height: normal;
}
.keep-open-label {
padding: 0 7px;
display: flex;
}
}
</style>

View File

@ -392,6 +392,7 @@ export const parseNotification = (data) => {
: parseUser(data.target)
output.from_profile = parseUser(data.account)
output.emoji = data.emoji
output.emoji_url = data.emoji_url
} else {
const parsedNotice = parseStatus(data.notice)
output.type = data.ntype