From d2456d5fea823a9659b437ae2d3cc876df7b25f9 Mon Sep 17 00:00:00 2001 From: eugenijm Date: Tue, 12 May 2020 23:27:16 +0300 Subject: [PATCH] Chat message deletion --- src/components/chat/chat.js | 17 ++++--- src/components/chat/chat.vue | 7 ++- src/components/chat_message/chat_message.js | 37 +++++++++++---- src/components/chat_message/chat_message.scss | 18 ++++---- src/components/chat_message/chat_message.vue | 46 +++++++++++++++---- src/components/chat_title/chat_title.vue | 5 +- src/components/side_drawer/side_drawer.vue | 5 +- src/i18n/en.json | 4 +- src/modules/chats.js | 17 +++++-- src/services/api/api.service.js | 12 ++++- src/services/chat_service/chat_service.js | 7 +++ .../entity_normalizer.service.js | 4 +- 12 files changed, 136 insertions(+), 43 deletions(-) diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js index 7d4c0313..f0f57a67 100644 --- a/src/components/chat/chat.js +++ b/src/components/chat/chat.js @@ -74,12 +74,16 @@ const Chat = { return this.$t('chats.write_message') } }, + customRef () { + return this.$store.state.chats.ref + }, ...mapGetters(['currentChat', 'currentChatMessageService', 'findUser']), ...mapState({ backendInteractor: state => state.api.backendInteractor, currentUser: state => state.users.currentUser, isMobileLayout: state => state.interface.mobileLayout, - openedChats: state => state.chats.openedChats + openedChats: state => state.chats.openedChats, + openedChatMessageServices: state => state.chats.openedChatMessageServices }) }, watch: { @@ -92,6 +96,11 @@ const Chat = { } }) }, + 'currentChatMessageService.messages.length': { + handler: function () { + this.chatViewItems = chatService.getView(this.currentChatMessageService) + } + }, '$route': function (prev, next) { this.recipientId = this.$route.params.recipient_id this.startFetching() @@ -108,11 +117,6 @@ const Chat = { this.scrollDown({ forceRead: true }) }) }, - onScopeNoticeDismissed () { - this.$nextTick(() => { - this.updateSize() - }) - }, onFilesDropped () { this.$nextTick(() => { this.updateSize() @@ -327,7 +331,6 @@ const Chat = { let bottomedOut = this.bottomedOut() this.loadingOlderMessages = false this.$store.dispatch('addChatMessages', { chatId, messages }).then(() => { - this.chatViewItems = chatService.getView(this.currentChatMessageService) if (positionBeforeLoading) { this.$nextTick(() => { let positionAfterLoading = this.getPosition() diff --git a/src/components/chat/chat.vue b/src/components/chat/chat.vue index dd8d849e..d070a02f 100644 --- a/src/components/chat/chat.vue +++ b/src/components/chat/chat.vue @@ -14,7 +14,10 @@ class="go-back-button" @click="goBack" > --> - +
--> - +
diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js index 5354aa00..afcd7b09 100644 --- a/src/components/chat_message/chat_message.js +++ b/src/components/chat_message/chat_message.js @@ -1,4 +1,5 @@ import { mapState, mapGetters } from 'vuex' +import Popover from '../popover/popover.vue' import Attachment from '../attachment/attachment.vue' import UserAvatar from '../user_avatar/user_avatar.vue' import Gallery from '../gallery/gallery.vue' @@ -16,6 +17,7 @@ const ChatMessage = { 'sequenceHovered' ], components: { + Popover, Attachment, StatusContent, UserAvatar, @@ -46,30 +48,45 @@ const ChatMessage = { return this.chatViewItem.type === 'message' }, messageForStatusContent () { - let result = { + return { summary: '', statusnet_html: this.message.content, - text: this.message.content + text: this.message.content, + attachments: this.message.attachments } - - if (this.message.attachment) { - result.attachments = [this.message.attachment] - } else { - result.attachments = [] - } - - return result }, ...mapState({ betterShadow: state => state.interface.browserSupport.cssFilter, currentUser: state => state.users.currentUser, restrictedNicknames: state => state.instance.restrictedNicknames }), + wrapperStyle () { + return { + 'opacity': this.hovered || this.menuOpened ? '1' : '0' + } + }, ...mapGetters(['mergedConfig', 'findUser']) }, + data () { + return { + hovered: false, + menuOpened: false + } + }, methods: { onHover (bool) { this.$emit('hover', { state: bool, sequenceId: this.chatViewItem.sequenceId }) + }, + async deleteMessage () { + const confirmed = window.confirm(this.$t('chats.delete_confirm')) + if (confirmed) { + await this.$store.dispatch('deleteChatMessage', { + messageId: this.chatViewItem.data.id, + chatId: this.chatViewItem.data.chat_id + }) + } + this.hovered = false + this.menuOpened = false } } } diff --git a/src/components/chat_message/chat_message.scss b/src/components/chat_message/chat_message.scss index 7c6f276c..b24c4458 100644 --- a/src/components/chat_message/chat_message.scss +++ b/src/components/chat_message/chat_message.scss @@ -24,16 +24,8 @@ .status { padding: 0.75em; - &:hover { - .chat-message-menu { - // visibility: visible; - opacity: 1; - } - } - .chat-message-menu { transition: opacity 0.1s; - // visibility: hidden; opacity: 0; button { @@ -41,6 +33,16 @@ padding-bottom: 3px; } } + + .icon-ellipsis { + cursor: pointer; + + &:hover, + .extra-button-popover.open & { + color: $fallback--text; + color: var(--text, $fallback--text); + } + } } .direct-conversation { diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue index a74c907b..fac66409 100644 --- a/src/components/chat_message/chat_message.vue +++ b/src/components/chat_message/chat_message.vue @@ -26,24 +26,54 @@
-
+
+ @mouseenter="hovered = true" + @mouseleave="hovered = false" + >
+ - +
+ +
+ +
+ :full-content="true" + > - + {{ $t("nav.dms") }} - + {{ $t("nav.chats") }} { // dispatch('refreshCurrentUser') }) + }, + deleteChatMessage ({ rootState, commit, dispatch }, value) { + rootState.api.backendInteractor.deleteChatMessage(value) + commit('deleteChatMessage', value) } }, mutations: { @@ -97,10 +102,10 @@ const chats = { }, addOpenedChat (state, { _dispatch, chat }) { state.currentChatId = chat.id - state.openedChats[chat.id] = chat + set(state.openedChats, chat.id, chat) if (!state.openedChatMessageServices[chat.id]) { - state.openedChatMessageServices[chat.id] = chatService.empty(chat.id) + set(state.openedChatMessageServices, chat.id, chatService.empty(chat.id)) } }, setCurrentChatId (state, { chatId }) { @@ -152,6 +157,12 @@ const chats = { chatService.add(chatMessageService, { messages: messages.map(parseChatMessage) }) } }, + deleteChatMessage (state, { chatId, messageId }) { + const chatMessageService = state.openedChatMessageServices[chatId] + if (chatMessageService) { + chatService.deleteMessage(chatMessageService, messageId) + } + }, resetChatNewMessageCount (state, _value) { const chatMessageService = state.openedChatMessageServices[state.currentChatId] chatService.resetNewMessageCount(chatMessageService) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 3a094bed..5c2bf2a2 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -82,6 +82,7 @@ const PLEROMA_CHATS_URL = `/api/v1/pleroma/chats` const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}` const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages` const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read` +const PLEROMA_DELETE_CHAT_MESSAGE_URL = (chatId, messageId) => `/api/v1/pleroma/chats/${chatId}/messages/${messageId}` const oldfetch = window.fetch @@ -1192,6 +1193,14 @@ const readChat = ({ id, credentials }) => { }) } +const deleteChatMessage = ({ chatId, messageId, credentials }) => { + return promisedRequest({ + url: PLEROMA_DELETE_CHAT_MESSAGE_URL(chatId, messageId), + method: 'DELETE', + credentials + }) +} + const apiService = { verifyCredentials, fetchTimeline, @@ -1273,7 +1282,8 @@ const apiService = { getOrCreateChat, chatMessages, postChatMessage, - readChat + readChat, + deleteChatMessage } export default apiService diff --git a/src/services/chat_service/chat_service.js b/src/services/chat_service/chat_service.js index 5f419249..7c76d10d 100644 --- a/src/services/chat_service/chat_service.js +++ b/src/services/chat_service/chat_service.js @@ -11,6 +11,12 @@ const empty = (chatId) => { } } +const deleteMessage = (storage, messageId) => { + if (!storage) { return } + storage.messages = storage.messages.filter(m => m.id !== messageId) + delete storage.idIndex[messageId] +} + const add = (storage, { messages: newMessages }) => { if (!storage) { return } for (let i = 0; i < newMessages.length; i++) { @@ -99,6 +105,7 @@ const ChatService = { add, empty, getView, + deleteMessage, resetNewMessageCount } diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 916e796d..79c8f1f5 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -389,7 +389,9 @@ export const parseChatMessage = (message) => { output.chat_id = parseInt(message.chat_id, 10) output.content = addEmojis(message.content, message.emojis) if (message.attachment) { - output.attachment = parseAttachment(message.attachment) + output.attachments = [parseAttachment(message.attachment)] + } else { + output.attachments = [] } return output }