Skip to content

Commit

Permalink
Merge pull request #662 from Adamant-im/feat/animate-all-incoming-rea…
Browse files Browse the repository at this point in the history
…ctions

feat: Animate all new incoming reactions
  • Loading branch information
bludnic authored Aug 29, 2024
2 parents 80ba3d8 + 2296dd2 commit ce2be8c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 78 deletions.
56 changes: 50 additions & 6 deletions src/components/AChat/AChatReactions/AChatReaction.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div
:class="{
[classes.emoji]: true,
[classes.emojiAnimate]: animate
[classes.emojiAnimate]: animationEnabled
}"
>
{{ asset.react_message }}
Expand All @@ -16,7 +16,10 @@
</template>

<script lang="ts">
import { defineComponent, PropType } from 'vue'
import { computed, defineComponent, PropType, ref, watch } from 'vue'
import { useStore } from 'vuex'
import { NormalizedChatMessageTransaction } from '@/lib/chat/helpers'
import { ReactionAsset } from '@/lib/adamant-api/asset'
const className = 'a-chat-reaction'
Expand All @@ -33,14 +36,55 @@ export default defineComponent({
type: Object as PropType<ReactionAsset>,
required: true
},
animate: {
type: Boolean,
reaction: {
type: Object as PropType<NormalizedChatMessageTransaction>,
required: true
},
partnerId: {
type: String,
required: true
}
},
setup() {
setup(props) {
const store = useStore()
const animationEnabled = ref(false)
const animate = () => {
if (animationEnabled.value) return
animationEnabled.value = true
setTimeout(() => {
animationEnabled.value = false
}, 1500)
}
const numOfNewMessages = computed(() => store.getters['chat/numOfNewMessages'](props.partnerId))
const isLastReaction = computed(() =>
store.getters['chat/isLastReaction'](props.reaction.id, props.partnerId)
)
const animateIncoming = computed(() => isLastReaction.value && numOfNewMessages.value === 0)
const animateOutgoing = computed(() => props.reaction.status === 'PENDING')
watch(numOfNewMessages, () => {
if (animateIncoming.value) {
animate()
}
})
watch(
() => props.reaction,
() => {
if (animateOutgoing.value) {
animate()
}
},
{ immediate: true }
)
return {
classes
classes,
animationEnabled
}
}
})
Expand Down
26 changes: 13 additions & 13 deletions src/components/AChat/AChatReactions/AChatReactions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
>
<a-chat-reaction
v-for="reaction of reactions"
:key="reaction.id"
:key="reaction.senderId"
:class="classes.reaction"
:reaction="reaction"
:asset="reaction.asset"
:animate="shouldAnimate(reaction)"
:partner-id="partnerId"
>
<template #avatar v-if="reaction.senderId === partnerId">
<ChatAvatar :user-id="partnerId" :size="16" />
Expand All @@ -24,8 +25,9 @@
import { usePartnerId } from '@/components/AChat/hooks/usePartnerId.ts'
import ChatAvatar from '@/components/Chat/ChatAvatar.vue'
import { isEmptyReaction, NormalizedChatMessageTransaction } from '@/lib/chat/helpers'
import { computed, defineComponent, PropType } from 'vue'
import { computed, defineComponent, PropType, watch } from 'vue'
import { useStore } from 'vuex'
import { vibrate } from '@/lib/vibrate'
import AChatReaction from './AChatReaction.vue'
const className = 'a-chat-reactions'
Expand Down Expand Up @@ -71,20 +73,18 @@ export default defineComponent({
return list.sort((left, right) => left.timestamp - right.timestamp)
})
const shouldAnimate = (reaction: NormalizedChatMessageTransaction) => {
const isLastReaction = store.getters['chat/isLastReaction'](reaction.id, partnerId.value)
return (
isLastReaction &&
(store.state.chat.animateIncomingReaction || store.state.chat.animateOutgoingReaction)
)
}
watch(
() => store.getters['chat/numOfNewMessages'](partnerId.value),
(numOfNewMessages) => {
if (numOfNewMessages > 0) vibrate.veryShort()
},
{ immediate: true }
)
return {
classes,
partnerId,
reactions,
shouldAnimate
reactions
}
}
})
Expand Down
1 change: 0 additions & 1 deletion src/components/Chat/Chat.vue
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,6 @@ export default {
beforeUnmount() {
window.removeEventListener('keyup', this.onKeyPress)
Visibility.unbind(this.visibilityId)
this.$store.dispatch('clearAnimationTimeouts')
},
mounted() {
if (this.isFulfilled && this.chatPage <= 0) this.fetchChatMessages()
Expand Down
5 changes: 0 additions & 5 deletions src/lib/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,3 @@ export const REACT_EMOJIS = {
FLUSHED_FACE: '😳',
PARTY_POPPER: '🎉'
}

export const AnimationReactionType = {
Incoming: 0,
Outgoing: 1
}
File renamed without changes.
53 changes: 3 additions & 50 deletions src/store/modules/chat/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,15 @@ import {
} from '@/lib/chat/helpers'
import { i18n } from '@/i18n'
import { isNumeric } from '@/lib/numericHelpers'
import {
Cryptos,
TransactionStatus as TS,
MessageType,
AnimationReactionType as ART
} from '@/lib/constants'
import { Cryptos, TransactionStatus as TS, MessageType } from '@/lib/constants'
import { isStringEqualCI } from '@/lib/textHelpers'
import { replyMessageAsset } from '@/lib/adamant-api/asset'
import { vibrate } from '@/lib/vibrate'

import { generateAdamantChats } from './utils/generateAdamantChats'
import { isAllNodesDisabledError, isAllNodesOfflineError } from '@/lib/nodes/utils/errors'

export let interval

export let timeouts = []

const SOCKET_ENABLED_TIMEOUT = 10000
const SOCKET_DISABLED_TIMEOUT = 3000

Expand Down Expand Up @@ -55,8 +47,6 @@ const state = () => ({
lastMessageHeight: 0, // `height` value of the last message
isFulfilled: false, // false - getChats did not start or in progress, true - getChats finished
offset: 0, // for loading chat list with pagination. -1 if all of chats loaded
animateIncomingReaction: false, // `true` - animate incoming last reaction
animateOutgoingReaction: false, // `true` - animate outgoing last reaction
noActiveNodesDialog: undefined // true - visible dialog, false - hidden dialog, but shown before, undefined - not shown
})

Expand Down Expand Up @@ -505,14 +495,6 @@ const mutations = {
}
},

updateAnimateOutgoingReaction(state, value) {
state.animateOutgoingReaction = value
},

updateAnimateIncomingReaction(state, value) {
state.animateIncomingReaction = value
},

setNoActiveNodesDialog(state, value) {
if (state.noActiveNodesDialog === false) {
return // do not show dialog again
Expand Down Expand Up @@ -652,7 +634,7 @@ const actions = {
* This is a temporary solution until the sockets are implemented.
* @returns {Promise}
*/
getNewMessages({ state, commit, dispatch, rootState }) {
getNewMessages({ state, commit, dispatch }) {
if (!state.isFulfilled) {
return Promise.reject(new Error('Chat is not fulfilled'))
}
Expand All @@ -662,10 +644,6 @@ const actions = {

dispatch('pushMessages', messages)

if (!rootState.options.useSocketConnection && messages.length > 0) {
dispatch('animateLastReaction', ART.Incoming)
}

if (lastMessageHeight > 0) {
commit('setHeight', lastMessageHeight)
}
Expand Down Expand Up @@ -842,16 +820,14 @@ const actions = {
* @param {string} reactMessage Emoji
* @returns {Promise}
*/
sendReaction({ dispatch, commit, rootState }, { recipientId, reactToId, reactMessage }) {
sendReaction({ commit, rootState }, { recipientId, reactToId, reactMessage }) {
const messageObject = createReaction({
recipientId,
senderId: rootState.address,
reactToId,
reactMessage
})

dispatch('animateLastReaction', ART.Outgoing)

commit('pushMessage', {
message: messageObject,
userId: rootState.address
Expand Down Expand Up @@ -888,22 +864,6 @@ const actions = {
})
},

/**
* Animation of last reaction with vibro
* @param {ART} type - animation reaction type - incoming or outgoing
*/
animateLastReaction({ commit }, type) {
const updateFn =
type === ART.Incoming ? 'updateAnimateIncomingReaction' : 'updateAnimateOutgoingReaction'

vibrate.veryShort()

commit(updateFn, true)
const timeout = setTimeout(() => commit(updateFn, false), 1500)

timeouts.push(timeout)
},

/**
* Fast crypto-transfer, to display transaction in chat
* before confirmation.
Expand Down Expand Up @@ -979,13 +939,6 @@ const actions = {
}
},

clearAnimationTimeouts: {
root: true,
handler() {
timeouts.forEach((timeout) => clearTimeout(timeout))
}
},

/** Resets module state **/
reset: {
root: true,
Expand Down
3 changes: 0 additions & 3 deletions src/store/plugins/socketsPlugin.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import socketClient from '@/lib/sockets'
import { AnimationReactionType as ART } from '@/lib/constants'
import { decodeChat, getPublicKey } from '@/lib/adamant-api'
import { isStringEqualCI } from '@/lib/textHelpers'

Expand All @@ -16,8 +15,6 @@ function subscribe(store) {
// Currently, we don't update confirmations for direct transfers, see getChats() in adamant-api.js
// So we'll update confirmations in getTransactionStatus()
store.dispatch('chat/pushMessages', [decoded])

store.dispatch('chat/animateLastReaction', ART.Incoming)
})
})
}
Expand Down

0 comments on commit ce2be8c

Please sign in to comment.