Keep mentions when editing a comment

Signed-off-by: Julius Härtl <jus@bitgrid.net>
This commit is contained in:
Julius Härtl
2020-01-31 14:46:56 +01:00
parent 41d286986b
commit ac39a0d92c
4 changed files with 30 additions and 11 deletions

View File

@@ -125,7 +125,8 @@ export default {
if (!this.$refs.contentEditable) { if (!this.$refs.contentEditable) {
return return
} }
const mentions = this.$refs.contentEditable.querySelectorAll('span[data-at-embedded]') const node = this.$refs.contentEditable.cloneNode(true)
const mentions = node.querySelectorAll('span[data-at-embedded]')
mentions.forEach(mention => { mentions.forEach(mention => {
// FIXME Adding a space after the mention should be improved to // FIXME Adding a space after the mention should be improved to
// do it or not based on the next element instead of always // do it or not based on the next element instead of always
@@ -133,7 +134,7 @@ export default {
mention.replaceWith(' @' + mention.firstElementChild.attributes['data-mention-id'].value + ' ') mention.replaceWith(' @' + mention.firstElementChild.attributes['data-mention-id'].value + ' ')
}) })
return rawToParsed(this.$refs.contentEditable.innerHTML) return rawToParsed(node.innerHTML)
}, },
/** /**

View File

@@ -6,7 +6,7 @@
<span class="has-tooltip username"> <span class="has-tooltip username">
{{ comment.actorDisplayName }} {{ comment.actorDisplayName }}
</span> </span>
<Actions v-if="!edit" @click.stop.prevent> <Actions v-show="canEdit && !edit">
<ActionButton icon="icon-rename" @click="showUpdateForm()"> <ActionButton icon="icon-rename" @click="showUpdateForm()">
{{ t('deck', 'Update') }} {{ t('deck', 'Update') }}
</ActionButton> </ActionButton>
@@ -14,16 +14,17 @@
{{ t('deck', 'Delete') }} {{ t('deck', 'Delete') }}
</ActionButton> </ActionButton>
</Actions> </Actions>
<Actions v-else @click.stop.prevent> <Actions v-if="edit">
<ActionButton icon="icon-close" @click="hideUpdateForm" /> <ActionButton icon="icon-close" @click="hideUpdateForm" />
</Actions> </Actions>
</div> </div>
<RichText v-if="!edit" <RichText v-show="!edit"
ref="richTextElement"
class="comment--content" class="comment--content"
:text="richText" :text="richText"
:arguments="richArgs" :arguments="richArgs"
:autolink="true" /> :autolink="true" />
<CommentForm v-else v-model="commentMsg" @submit="updateComment" /> <CommentForm v-if="edit" v-model="commentMsg" @submit="updateComment" />
</template> </template>
</li> </li>
</template> </template>
@@ -32,6 +33,21 @@
import { Avatar, Actions, ActionButton, UserBubble } from '@nextcloud/vue' import { Avatar, Actions, ActionButton, UserBubble } from '@nextcloud/vue'
import RichText from '@juliushaertl/vue-richtext' import RichText from '@juliushaertl/vue-richtext'
import CommentForm from './CommentForm' import CommentForm from './CommentForm'
import { getCurrentUser } from '@nextcloud/auth'
const AtMention = {
name: 'AtMention',
functional: true,
render(createElement, context) {
const { user, displayName } = context.props
return createElement(
'span',
{ attrs: { 'data-at-embedded': true, 'contenteditable': false } },
[createElement(UserBubble, { props: { user, displayName }, attrs: { 'data-mention-id': user } })]
)
},
}
export default { export default {
name: 'CommentItem', name: 'CommentItem',
components: { components: {
@@ -55,6 +71,9 @@ export default {
}, },
computed: { computed: {
canEdit() {
return this.comment.actorId === getCurrentUser().uid
},
richText() { richText() {
let message = this.parsedMessage let message = this.parsedMessage
this.comment.mentions.forEach((mention, index) => { this.comment.mentions.forEach((mention, index) => {
@@ -68,7 +87,7 @@ export default {
const result = mentions.reduce(function(result, item, index) { const result = mentions.reduce(function(result, item, index) {
const itemKey = 'user-' + item.mentionId const itemKey = 'user-' + item.mentionId
result[itemKey] = { result[itemKey] = {
component: UserBubble, component: AtMention,
props: { props: {
user: item.mentionId, user: item.mentionId,
displayName: item.mentionDisplayName, displayName: item.mentionDisplayName,
@@ -88,7 +107,7 @@ export default {
methods: { methods: {
showUpdateForm() { showUpdateForm() {
this.commentMsg = this.comment.message this.commentMsg = this.$refs.richTextElement.$el.innerHTML
this.edit = true this.edit = true
}, },
hideUpdateForm() { hideUpdateForm() {

View File

@@ -26,7 +26,6 @@
<div v-if="card.commentsUnread > 0" class="icon icon-comment" /> <div v-if="card.commentsUnread > 0" class="icon icon-comment" />
<div v-if="card.duedate" :class="dueIcon"> <div v-if="card.duedate" :class="dueIcon">
<span>{{ dueTime }}</span> <span>{{ dueTime }}</span>
</div> </div>

View File

@@ -77,7 +77,7 @@ export default {
state.comments[cardId].comments.forEach(_comment => { state.comments[cardId].comments.forEach(_comment => {
Vue.set(_comment, 'isUnread', false) Vue.set(_comment, 'isUnread', false)
}) })
} },
}, },
actions: { actions: {
async fetchComments({ commit }, { cardId, offset }) { async fetchComments({ commit }, { cardId, offset }) {
@@ -119,6 +119,6 @@ export default {
async markCommentsAsRead({ commit }, cardId) { async markCommentsAsRead({ commit }, cardId) {
await apiClient.markCommentsAsRead(cardId) await apiClient.markCommentsAsRead(cardId)
await commit('markCommentsAsRead', cardId) await commit('markCommentsAsRead', cardId)
} },
}, },
} }