+
@@ -788,19 +790,33 @@ $status-margin: 0.75em;
.emoji-reactions {
display: flex;
- margin-top: 0.75em;
+ 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 {
diff --git a/src/modules/statuses.js b/src/modules/statuses.js
index c285b452..fcb6d1f3 100644
--- a/src/modules/statuses.js
+++ b/src/modules/statuses.js
@@ -1,4 +1,20 @@
-import { remove, slice, each, findIndex, find, maxBy, minBy, merge, first, last, isArray, omitBy, findKey } from 'lodash'
+import {
+ remove,
+ slice,
+ each,
+ findIndex,
+ find,
+ maxBy,
+ minBy,
+ merge,
+ first,
+ last,
+ isArray,
+ omitBy,
+ flow,
+ filter,
+ keys
+} from 'lodash'
import { set } from 'vue'
import apiService from '../services/api/api.service.js'
// import parse from '../services/status_parser/status_parser.js'
@@ -512,8 +528,29 @@ export const mutations = {
},
addEmojiReactions (state, { id, emojiReactions, currentUser }) {
const status = state.allStatusesObject[id]
- status.emojiReactions = emojiReactions
- status.reactedWithEmoji = findKey(emojiReactions, { id: currentUser.id })
+ set(status, 'emojiReactions', emojiReactions)
+ const reactedWithEmoji = flow(keys, filter(reaction => find(reaction, { id: currentUser.id })))(emojiReactions)
+ set(status, 'reactedWithEmoji', reactedWithEmoji)
+ },
+ addOwnReaction (state, { id, emoji, currentUser }) {
+ const status = state.allStatusesObject[id]
+ status.emojiReactions = status.emojiReactions || {}
+ const listOfUsers = (status.emojiReactions && status.emojiReactions[emoji]) || []
+ const hasSelfAlready = !!find(listOfUsers, { id: currentUser.id })
+ if (!hasSelfAlready) {
+ set(status.emojiReactions, emoji, listOfUsers.concat([{ id: currentUser.id }]))
+ set(status, 'reactedWithEmoji', emoji)
+ }
+ },
+ removeOwnReaction (state, { id, emoji, currentUser }) {
+ const status = state.allStatusesObject[id]
+ const listOfUsers = status.emojiReactions[emoji] || []
+ const hasSelfAlready = !!find(listOfUsers, { id: currentUser.id })
+ if (hasSelfAlready) {
+ const newUsers = filter(listOfUsers, user => user.id !== currentUser.id)
+ set(status.emojiReactions, emoji, newUsers)
+ set(status, 'reactedWith', emoji)
+ }
},
updateStatusWithPoll (state, { id, poll }) {
const status = state.allStatusesObject[id]
@@ -616,6 +653,24 @@ const statuses = {
commit('addRepeats', { id, rebloggedByUsers, currentUser: rootState.users.currentUser })
})
},
+ reactWithEmoji ({ rootState, dispatch, commit }, { id, emoji }) {
+ const currentUser = rootState.users.currentUser
+ commit('addOwnReaction', { id, emoji, currentUser })
+ rootState.api.backendInteractor.reactWithEmoji(id, emoji).then(
+ status => {
+ dispatch('fetchEmojiReactions', id)
+ }
+ )
+ },
+ unreactWithEmoji ({ rootState, dispatch, commit }, { id, emoji }) {
+ const currentUser = rootState.users.currentUser
+ commit('removeOwnReaction', { id, emoji, currentUser })
+ rootState.api.backendInteractor.unreactWithEmoji(id, emoji).then(
+ status => {
+ dispatch('fetchEmojiReactions', id)
+ }
+ )
+ },
fetchEmojiReactions ({ rootState, commit }, id) {
rootState.api.backendInteractor.fetchEmojiReactions(id).then(
emojiReactions => {
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index 7ef4b74a..2e96264a 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -72,6 +72,8 @@ const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute`
const MASTODON_SEARCH_2 = `/api/v2/search`
const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search'
const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/emoji_reactions_by`
+const PLEROMA_EMOJI_REACT_URL = id => `/api/v1/pleroma/statuses/${id}/react_with_emoji`
+const PLEROMA_EMOJI_UNREACT_URL = id => `/api/v1/pleroma/statuses/${id}/unreact_with_emoji`
const oldfetch = window.fetch
@@ -869,6 +871,24 @@ const fetchEmojiReactions = ({ id }) => {
return promisedRequest({ url: PLEROMA_EMOJI_REACTIONS_URL(id) })
}
+const reactWithEmoji = ({ id, emoji, credentials }) => {
+ return promisedRequest({
+ url: PLEROMA_EMOJI_REACT_URL(id),
+ method: 'POST',
+ credentials,
+ payload: { emoji }
+ }).then(status => parseStatus(status))
+}
+
+const unreactWithEmoji = ({ id, emoji, credentials }) => {
+ return promisedRequest({
+ url: PLEROMA_EMOJI_UNREACT_URL(id),
+ method: 'POST',
+ credentials,
+ payload: { emoji }
+ }).then(parseStatus)
+}
+
const reportUser = ({ credentials, userId, statusIds, comment, forward }) => {
return promisedRequest({
url: MASTODON_REPORT_USER_URL,
@@ -1003,6 +1023,8 @@ const apiService = {
fetchFavoritedByUsers,
fetchRebloggedByUsers,
fetchEmojiReactions,
+ reactWithEmoji,
+ unreactWithEmoji,
reportUser,
updateNotificationSettings,
search2,
diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js
index 52234fcc..44233a24 100644
--- a/src/services/backend_interactor_service/backend_interactor_service.js
+++ b/src/services/backend_interactor_service/backend_interactor_service.js
@@ -144,6 +144,8 @@ const backendInteractorService = credentials => {
const fetchFavoritedByUsers = (id) => apiService.fetchFavoritedByUsers({ id })
const fetchRebloggedByUsers = (id) => apiService.fetchRebloggedByUsers({ id })
const fetchEmojiReactions = (id) => apiService.fetchEmojiReactions({ id })
+ const reactWithEmoji = (id, emoji) => apiService.reactWithEmoji({ id, emoji, credentials })
+ const unreactWithEmoji = (id, emoji) => apiService.unreactWithEmoji({ id, emoji, credentials })
const reportUser = (params) => apiService.reportUser({ credentials, ...params })
const favorite = (id) => apiService.favorite({ id, credentials })
@@ -212,6 +214,8 @@ const backendInteractorService = credentials => {
fetchFavoritedByUsers,
fetchRebloggedByUsers,
fetchEmojiReactions,
+ reactWithEmoji,
+ unreactWithEmoji,
reportUser,
favorite,
unfavorite,