forked from AkkomaGang/akkoma-fe
Chat message deletion
This commit is contained in:
parent
855f36eeda
commit
d2456d5fea
12 changed files with 136 additions and 43 deletions
|
@ -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()
|
||||
|
|
|
@ -14,7 +14,10 @@
|
|||
class="go-back-button"
|
||||
@click="goBack"
|
||||
> -->
|
||||
<i class="button-icon icon-left-open" @click="goBack" />
|
||||
<i
|
||||
class="button-icon icon-left-open"
|
||||
@click="goBack"
|
||||
/>
|
||||
<!-- </a> -->
|
||||
<div class="title text-center">
|
||||
<ChatTitle
|
||||
|
@ -35,7 +38,7 @@
|
|||
style="margin-right: 0.3em;"
|
||||
@click="goBack"
|
||||
> -->
|
||||
<i class="button-icon icon-info-circled" />
|
||||
<i class="button-icon icon-info-circled" />
|
||||
<!-- </a> -->
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -26,24 +26,54 @@
|
|||
</router-link>
|
||||
</div>
|
||||
<div class="direct-conversation-inner">
|
||||
<div class="status-body" :style="{ 'min-width': message.attachment ? '80%' : '' }">
|
||||
<div
|
||||
class="status-body"
|
||||
:style="{ 'min-width': message.attachment ? '80%' : '' }"
|
||||
>
|
||||
<div
|
||||
class="media status"
|
||||
style="position: relative"
|
||||
>
|
||||
@mouseenter="hovered = true"
|
||||
@mouseleave="hovered = false"
|
||||
>
|
||||
<div
|
||||
v-if="isCurrentUser"
|
||||
class="chat-message-menu"
|
||||
style="position: absolute; right: 5px; top: -10px"
|
||||
:style="wrapperStyle"
|
||||
>
|
||||
<Popover
|
||||
trigger="click"
|
||||
placement="top"
|
||||
:bound-to="{ x: 'container' }"
|
||||
@show="menuOpened = true"
|
||||
@close="menuOpened = false"
|
||||
>
|
||||
<button
|
||||
title="more"
|
||||
>
|
||||
<i class="icon-dot-3" />
|
||||
</button>
|
||||
<div
|
||||
slot="content"
|
||||
slot-scope=""
|
||||
>
|
||||
<div class="dropdown-menu">
|
||||
<button
|
||||
class="dropdown-item dropdown-item-icon"
|
||||
@click="deleteMessage"
|
||||
>
|
||||
<i class="icon-cancel" /> {{ $t("chats.delete") }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
slot="trigger"
|
||||
:title="$t('chats.more')"
|
||||
>
|
||||
<i class="icon-dot-3" />
|
||||
</button>
|
||||
</Popover>
|
||||
</div>
|
||||
<StatusContent
|
||||
:status="messageForStatusContent"
|
||||
:full-content="true">
|
||||
:full-content="true"
|
||||
>
|
||||
<span
|
||||
slot="footer"
|
||||
class="created-at"
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
width="23px"
|
||||
height="23px"
|
||||
/>
|
||||
<span v-if="withAvatar" style="margin-right: 0.5em" />
|
||||
<span
|
||||
v-if="withAvatar"
|
||||
style="margin-right: 0.5em"
|
||||
/>
|
||||
<span
|
||||
v-for="(user, index) in otherUsersTruncated"
|
||||
:key="user.id"
|
||||
|
|
|
@ -46,7 +46,10 @@
|
|||
<router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
|
||||
<i class="button-icon icon-mail-alt" /> {{ $t("nav.dms") }}
|
||||
</router-link>
|
||||
<router-link :to="{ name: 'chats', params: { username: currentUser.screen_name } }" style="position: relative">
|
||||
<router-link
|
||||
:to="{ name: 'chats', params: { username: currentUser.screen_name } }"
|
||||
style="position: relative"
|
||||
>
|
||||
<i class="button-icon icon-chat" /> {{ $t("nav.chats") }}
|
||||
<span
|
||||
v-if="unreadChatCount(currentChat)"
|
||||
|
|
|
@ -759,7 +759,9 @@
|
|||
"delete": "Delete",
|
||||
"chats": "Chats",
|
||||
"new": "New Chat",
|
||||
"empty_message_error": "Cannot post empty message"
|
||||
"empty_message_error": "Cannot post empty message",
|
||||
"more": "More",
|
||||
"delete_confirm": "Do you really want to delete this message?"
|
||||
},
|
||||
"display_date": {
|
||||
"today": "Today"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { set } from 'vue'
|
||||
import { find, omitBy, debounce, last } from 'lodash'
|
||||
import chatService from '../services/chat_service/chat_service.js'
|
||||
import { parseChat, parseChatMessage } from '../services/entity_normalizer/entity_normalizer.service.js'
|
||||
|
@ -57,7 +58,7 @@ const chats = {
|
|||
setCurrentChatFetcher ({ rootState, commit }, { fetcher }) {
|
||||
commit('setCurrentChatFetcher', { fetcher })
|
||||
},
|
||||
addOpenedChat ({ commit, dispatch }, { chat }) {
|
||||
addOpenedChat ({ rootState, commit, dispatch }, { chat }) {
|
||||
commit('addOpenedChat', { dispatch, chat: parseChat(chat) })
|
||||
dispatch('addNewUsers', [chat.account])
|
||||
},
|
||||
|
@ -85,6 +86,10 @@ const chats = {
|
|||
rootState.api.backendInteractor.readChat({ id }).then(() => {
|
||||
// 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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue