summaryrefslogtreecommitdiffstats
path: root/apps/comments
diff options
context:
space:
mode:
authorgreta <gretadoci@gmail.com>2024-08-14 13:52:19 +0200
committerFerdinand Thiessen <opensource@fthiessen.de>2024-08-24 12:45:42 +0200
commitf27611f0727f0ef8f374ba6d1d820212718aab6b (patch)
tree47dae89bee7e9d743842b30803e7ecde3c60942f /apps/comments
parent05820ab873240d7fa0e538f48b4956d7ab4f3356 (diff)
downloadnextcloud-server-f27611f0727f0ef8f374ba6d1d820212718aab6b.tar.gz
nextcloud-server-f27611f0727f0ef8f374ba6d1d820212718aab6b.zip
fix: Handle comment deletion correctly
Signed-off-by: greta <gretadoci@gmail.com>
Diffstat (limited to 'apps/comments')
-rw-r--r--apps/comments/src/comments-activity-tab.ts49
-rw-r--r--apps/comments/src/components/Comment.vue34
-rw-r--r--apps/comments/src/mixins/CommentMixin.js31
-rw-r--r--apps/comments/src/services/CommentsInstance.js32
-rw-r--r--apps/comments/src/store/deletedCommentLimbo.js28
5 files changed, 84 insertions, 90 deletions
diff --git a/apps/comments/src/comments-activity-tab.ts b/apps/comments/src/comments-activity-tab.ts
index 0cb3bf70bbb..f38484d25e7 100644
--- a/apps/comments/src/comments-activity-tab.ts
+++ b/apps/comments/src/comments-activity-tab.ts
@@ -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
@@ -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: () => {
@@ -59,12 +50,17 @@ 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,
@@ -72,10 +68,9 @@ export function registerCommentsPlugins() {
reloadCallback: reload,
},
})
- this._CommentsViewInstance.$mount(element)
},
unmount() {
- this._CommentsViewInstance.$destroy()
+ this._CommentsViewInstance?.$destroy()
},
}))
})
diff --git a/apps/comments/src/components/Comment.vue b/apps/comments/src/components/Comment.vue
index 644b0c0e059..6a02bcd8c6a 100644
--- a/apps/comments/src/components/Comment.vue
+++ b/apps/comments/src/components/Comment.vue
@@ -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 -->
@@ -138,6 +121,8 @@ import IconDelete from 'vue-material-design-icons/Delete.vue'
import IconEdit from 'vue-material-design-icons/Pencil.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')
@@ -210,6 +195,7 @@ export default {
},
computed: {
+ ...mapStores(useDeletedCommentLimbo),
/**
* Is the current user the author of this comment
@@ -242,6 +228,10 @@ export default {
timestamp() {
return Date.parse(this.creationDateTime)
},
+
+ isLimbo() {
+ return this.deletedCommentLimboStore.checkForId(this.id)
+ },
},
watch: {
@@ -355,7 +345,7 @@ $comment-padding: 10px;
&__submit {
position: absolute !important;
- bottom: 0;
+ bottom: 5px;
right: 0;
}
diff --git a/apps/comments/src/mixins/CommentMixin.js b/apps/comments/src/mixins/CommentMixin.js
index cf93dead9ba..722ad3444ce 100644
--- a/apps/comments/src/mixins/CommentMixin.js
+++ b/apps/comments/src/mixins/CommentMixin.js
@@ -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 {
@@ -54,6 +39,10 @@ export default {
}
},
+ computed: {
+ ...mapStores(useDeletedCommentLimbo),
+ },
+
methods: {
// EDITION
onEdit() {
@@ -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() {
@@ -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)
}
},
diff --git a/apps/comments/src/services/CommentsInstance.js b/apps/comments/src/services/CommentsInstance.js
index f71763a5591..cc45d0cbea7 100644
--- a/apps/comments/src/services/CommentsInstance.js
+++ b/apps/comments/src/services/CommentsInstance.js
@@ -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({
@@ -51,6 +36,8 @@ 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,
@@ -58,6 +45,7 @@ export default class CommentInstance {
...(options.propsData ?? {}),
resourceType,
},
+ pinia,
}
// Init Comments component
const View = Vue.extend(CommentsApp)
diff --git a/apps/comments/src/store/deletedCommentLimbo.js b/apps/comments/src/store/deletedCommentLimbo.js
new file mode 100644
index 00000000000..3e511addebb
--- /dev/null
+++ b/apps/comments/src/store/deletedCommentLimbo.js
@@ -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)
+ },
+ },
+})