Skip to content

Commit

Permalink
stable28: fix comment deletion
Browse files Browse the repository at this point in the history
Signed-off-by: greta <gretadoci@gmail.com>
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
  • Loading branch information
GretaD authored and nextcloud-command committed Aug 19, 2024
1 parent 14bf5c4 commit 10b81ed
Show file tree
Hide file tree
Showing 25 changed files with 135 additions and 168 deletions.
49 changes: 22 additions & 27 deletions apps/comments/src/comments-activity-tab.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,16 @@
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import moment from '@nextcloud/moment'
import Vue from 'vue'
import Vue, { type ComponentPublicInstance } from 'vue'
import logger from './logger.js'
import { getComments } from './services/GetComments.js'

import { PiniaVuePlugin, createPinia } from 'pinia'

Vue.use(PiniaVuePlugin)

let ActivityTabPluginView
let ActivityTabPluginInstance

Expand All @@ -33,18 +20,22 @@ let ActivityTabPluginInstance
export function registerCommentsPlugins() {
window.OCA.Activity.registerSidebarAction({
mount: async (el, { context, fileInfo, reload }) => {
const pinia = createPinia()

if (!ActivityTabPluginView) {
const { default: ActivityCommmentAction } = await import('./views/ActivityCommentAction.vue')
ActivityTabPluginView = Vue.extend(ActivityCommmentAction)
const { default: ActivityCommentAction } = await import('./views/ActivityCommentAction.vue')
/** @ts-expect-error Types are broken for Vue2 */
ActivityTabPluginView = Vue.extend(ActivityCommentAction)
}
ActivityTabPluginInstance = new ActivityTabPluginView({
el,
parent: context,
pinia,
propsData: {
reloadCallback: reload,
resourceId: fileInfo.id,
},
})
ActivityTabPluginInstance.$mount(el)
logger.info('Comments plugin mounted in Activity sidebar action', { fileInfo })
},
unmount: () => {
Expand All @@ -59,23 +50,27 @@ export function registerCommentsPlugins() {
const { data: comments } = await getComments({ resourceType: 'files', resourceId: fileInfo.id }, { limit, offset })
logger.debug('Loaded comments', { fileInfo, comments })
const { default: CommentView } = await import('./views/ActivityCommentEntry.vue')
/** @ts-expect-error Types are broken for Vue2 */
const CommentsViewObject = Vue.extend(CommentView)

return comments.map((comment) => ({
timestamp: moment(comment.props.creationDateTime).toDate().getTime(),
mount(element, { context, reload }) {
_CommentsViewInstance: undefined as ComponentPublicInstance | undefined,

timestamp: moment(comment.props?.creationDateTime).toDate().getTime(),

mount(element: HTMLElement, { context, reload }) {
this._CommentsViewInstance = new CommentsViewObject({
el: element,
parent: context,
propsData: {
comment,
resourceId: fileInfo.id,
reloadCallback: reload,
},
})
this._CommentsViewInstance.$mount(element)
},
unmount() {
this._CommentsViewInstance.$destroy()
this._CommentsViewInstance?.$destroy()
},
}))
})
Expand Down
53 changes: 24 additions & 29 deletions apps/comments/src/components/Comment.vue
Original file line number Diff line number Diff line change
@@ -1,27 +1,10 @@
<!--
- @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
-
- @author John Molakvoæ <skjnldsv@protonmail.com>
-
- @license GNU AGPL version 3 or any later version
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as
- published by the Free Software Foundation, either version 3 of the
- License, or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-->
- SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
- SPDX-License-Identifier: AGPL-3.0-or-later
-->
<template>
<component :is="tag"
v-show="!deleted"
v-show="!deleted && !isLimbo"
:class="{'comment--loading': loading}"
class="comment">
<!-- Comment header toolbar -->
Expand Down Expand Up @@ -69,7 +52,10 @@
<div v-if="id && loading" class="comment_loading icon-loading-small" />

<!-- Relative time to the comment creation -->
<Moment v-else-if="creationDateTime" class="comment__timestamp" :timestamp="timestamp" />
<NcDateTime v-else-if="creationDateTime"
class="comment__timestamp"
:timestamp="timestamp"
:ignore-seconds="true" />
</div>

<!-- Message editor -->
Expand Down Expand Up @@ -119,22 +105,24 @@
<script>
import { getCurrentUser } from '@nextcloud/auth'
import { translate as t } from '@nextcloud/l10n'
import moment from '@nextcloud/moment'

import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActions from '@nextcloud/vue/dist/Components/NcActions.js'
import NcActionSeparator from '@nextcloud/vue/dist/Components/NcActionSeparator.js'
import NcAvatar from '@nextcloud/vue/dist/Components/NcAvatar.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import RichEditorMixin from '@nextcloud/vue/dist/Mixins/richEditor.js'

import IconArrowRight from 'vue-material-design-icons/ArrowRight.vue'
import IconClose from 'vue-material-design-icons/Close.vue'
import IconDelete from 'vue-material-design-icons/Delete.vue'
import IconEdit from 'vue-material-design-icons/Pencil.vue'

import Moment from './Moment.vue'
import CommentMixin from '../mixins/CommentMixin.js'
import { mapStores } from 'pinia'
import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.js'

// Dynamic loading
const NcRichContenteditable = () => import('@nextcloud/vue/dist/Components/NcRichContenteditable.js')
Expand All @@ -147,15 +135,15 @@ export default {
IconClose,
IconDelete,
IconEdit,
Moment,
NcActionButton,
NcActions,
NcActionSeparator,
NcAvatar,
NcButton,
NcDateTime,
NcLoadingIcon,
NcRichContenteditable,
},

mixins: [RichEditorMixin, CommentMixin],

inheritAttrs: false,
Expand Down Expand Up @@ -207,6 +195,7 @@ export default {
},

computed: {
...mapStores(useDeletedCommentLimbo),

/**
* Is the current user the author of this comment
Expand All @@ -233,9 +222,15 @@ export default {
return !this.localMessage || this.localMessage.trim() === ''
},

/**
* Timestamp of the creation time (in ms UNIX time)
*/
timestamp() {
// seconds, not milliseconds
return parseInt(moment(this.creationDateTime).format('x'), 10) / 1000
return Date.parse(this.creationDateTime)
},

isLimbo() {
return this.deletedCommentLimboStore.checkForId(this.id)
},
},

Expand Down Expand Up @@ -350,7 +345,7 @@ $comment-padding: 10px;

&__submit {
position: absolute !important;
bottom: 0;
bottom: 5px;
right: 0;
}

Expand Down
31 changes: 12 additions & 19 deletions apps/comments/src/mixins/CommentMixin.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,14 @@
/**
* @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { showError, showUndo, TOAST_UNDO_TIMEOUT } from '@nextcloud/dialogs'
import NewComment from '../services/NewComment.js'
import DeleteComment from '../services/DeleteComment.js'
import EditComment from '../services/EditComment.js'
import { mapStores } from 'pinia'
import { useDeletedCommentLimbo } from '../store/deletedCommentLimbo.js'
import logger from '../logger.js'

export default {
Expand Down Expand Up @@ -54,6 +39,10 @@ export default {
}
},

computed: {
...mapStores(useDeletedCommentLimbo),
},

methods: {
// EDITION
onEdit() {
Expand Down Expand Up @@ -81,11 +70,14 @@ export default {

// DELETION
onDeleteWithUndo() {
this.$emit('delete')
this.deleted = true
this.deletedCommentLimboStore.addId(this.id)
const timeOutDelete = setTimeout(this.onDelete, TOAST_UNDO_TIMEOUT)
showUndo(t('comments', 'Comment deleted'), () => {
clearTimeout(timeOutDelete)
this.deleted = false
this.deletedCommentLimboStore.removeId(this.id)
})
},
async onDelete() {
Expand All @@ -97,6 +89,7 @@ export default {
showError(t('comments', 'An error occurred while trying to delete the comment'))
console.error(error)
this.deleted = false
this.deletedCommentLimboStore.removeId(this.id)
}
},

Expand Down
32 changes: 10 additions & 22 deletions apps/comments/src/services/CommentsInstance.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,18 @@
/**
* @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { translate as t, translatePlural as n } from '@nextcloud/l10n'
import { getRequestToken } from '@nextcloud/auth'
import { getCSPNonce } from '@nextcloud/auth'
import { t, n } from '@nextcloud/l10n'
import { PiniaVuePlugin, createPinia } from 'pinia'
import Vue from 'vue'
import CommentsApp from '../views/Comments.vue'
import logger from '../logger.js'

Vue.use(PiniaVuePlugin)
// eslint-disable-next-line camelcase
__webpack_nonce__ = btoa(getRequestToken())
__webpack_nonce__ = getCSPNonce()

// Add translates functions
Vue.mixin({
Expand All @@ -51,13 +36,16 @@ export default class CommentInstance {
* @param {object} options the vue options (propsData, parent, el...)
*/
constructor(resourceType = 'files', options = {}) {
const pinia = createPinia()

// Merge options and set `resourceType` property
options = {
...options,
propsData: {
...(options.propsData ?? {}),
resourceType,
},
pinia,
}
// Init Comments component
const View = Vue.extend(CommentsApp)
Expand Down
28 changes: 28 additions & 0 deletions apps/comments/src/store/deletedCommentLimbo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { defineStore } from 'pinia'

export const useDeletedCommentLimbo = defineStore('deletedCommentLimbo', {
state: () => ({
idsInLimbo: [],
}),
actions: {
addId(id) {
this.idsInLimbo.push(id)
},

removeId(id) {
const index = this.idsInLimbo.indexOf(id)
if (index > -1) {
this.idsInLimbo.splice(index, 1)
}
},

checkForId(id) {
this.idsInLimbo.includes(id)
},
},
})
Loading

0 comments on commit 10b81ed

Please sign in to comment.