diff options
Diffstat (limited to 'apps/comments/src')
24 files changed, 229 insertions, 511 deletions
diff --git a/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts b/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts index aabbf42fadb..e8020f1f029 100644 --- a/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts +++ b/apps/comments/src/actions/inlineUnreadCommentsAction.spec.ts @@ -1,27 +1,11 @@ /** - * @copyright Copyright (c) 2023 Lucas Azevedo <lhs_azevedo@hotmail.com> - * - * @author Lucas Azevedo <lhs_azevedo@hotmail.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: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { action } from './inlineUnreadCommentsAction' -import { expect } from '@jest/globals' import { File, Permission, View, FileAction } from '@nextcloud/files' +import { describe, expect, test, vi } from 'vitest' + +import { action } from './inlineUnreadCommentsAction' import logger from '../logger' const view = { @@ -46,7 +30,7 @@ describe('Inline unread comments action display name tests', () => { expect(action.id).toBe('comments-unread') expect(action.displayName([file], view)).toBe('') expect(action.title!([file], view)).toBe('1 new comment') - expect(action.iconSvgInline([], view)).toBe('<svg>SvgMock</svg>') + expect(action.iconSvgInline([], view)).toMatch(/<svg.+<\/svg>/) expect(action.enabled!([file], view)).toBe(true) expect(action.inline!(file, view)).toBe(true) expect(action.default).toBeUndefined() @@ -132,8 +116,8 @@ describe('Inline unread comments action enabled tests', () => { describe('Inline unread comments action execute tests', () => { test('Action opens sidebar', async () => { - const openMock = jest.fn() - const setActiveTabMock = jest.fn() + const openMock = vi.fn() + const setActiveTabMock = vi.fn() window.OCA = { Files: { Sidebar: { @@ -162,8 +146,8 @@ describe('Inline unread comments action execute tests', () => { }) test('Action handles sidebar open failure', async () => { - const openMock = jest.fn(() => { throw new Error('Mock error') }) - const setActiveTabMock = jest.fn() + const openMock = vi.fn(() => { throw new Error('Mock error') }) + const setActiveTabMock = vi.fn() window.OCA = { Files: { Sidebar: { @@ -172,7 +156,7 @@ describe('Inline unread comments action execute tests', () => { }, }, } - jest.spyOn(logger, 'error').mockImplementation(() => jest.fn()) + vi.spyOn(logger, 'error').mockImplementation(() => vi.fn()) const file = new File({ id: 1, diff --git a/apps/comments/src/actions/inlineUnreadCommentsAction.ts b/apps/comments/src/actions/inlineUnreadCommentsAction.ts index b537923b30e..0afd93d7606 100644 --- a/apps/comments/src/actions/inlineUnreadCommentsAction.ts +++ b/apps/comments/src/actions/inlineUnreadCommentsAction.ts @@ -1,23 +1,6 @@ /** - * @copyright Copyright (c) 2023 Lucas Azevedo <lhs_azevedo@hotmail.com> - * - * @author Lucas Azevedo <lhs_azevedo@hotmail.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: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ import { FileAction, Node } from '@nextcloud/files' import { translate as t, translatePlural as n } from '@nextcloud/l10n' diff --git a/apps/comments/src/comments-activity-tab.ts b/apps/comments/src/comments-activity-tab.ts index 0cb3bf70bbb..77f6c9bca04 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 @@ -32,19 +19,22 @@ let ActivityTabPluginInstance */ export function registerCommentsPlugins() { window.OCA.Activity.registerSidebarAction({ - mount: async (el, { context, fileInfo, reload }) => { + mount: async (el, { 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({ - parent: context, + el, + pinia, propsData: { reloadCallback: reload, resourceId: fileInfo.id, }, }) - ActivityTabPluginInstance.$mount(el) logger.info('Comments plugin mounted in Activity sidebar action', { fileInfo }) }, unmount: () => { @@ -59,23 +49,26 @@ 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, { reload }) { this._CommentsViewInstance = new CommentsViewObject({ - parent: context, + el: element, propsData: { comment, resourceId: fileInfo.id, reloadCallback: reload, }, }) - this._CommentsViewInstance.$mount(element) }, unmount() { - this._CommentsViewInstance.$destroy() + this._CommentsViewInstance?.$destroy() }, })) }) diff --git a/apps/comments/src/comments-app.js b/apps/comments/src/comments-app.js index eca3deb8b24..a91a4bb37bb 100644 --- a/apps/comments/src/comments-app.js +++ b/apps/comments/src/comments-app.js @@ -1,23 +1,6 @@ /** - * @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 CommentsInstance from './services/CommentsInstance.js' diff --git a/apps/comments/src/comments-tab.js b/apps/comments/src/comments-tab.js index 73038412bd3..d3ebe3e9596 100644 --- a/apps/comments/src/comments-tab.js +++ b/apps/comments/src/comments-tab.js @@ -1,33 +1,16 @@ /** - * @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 */ // eslint-disable-next-line n/no-missing-import, import/no-unresolved import MessageReplyText from '@mdi/svg/svg/message-reply-text.svg?raw' -import { getRequestToken } from '@nextcloud/auth' +import { getCSPNonce } from '@nextcloud/auth' import { loadState } from '@nextcloud/initial-state' import { registerCommentsPlugins } from './comments-activity-tab.ts' // @ts-expect-error __webpack_nonce__ is injected by webpack -__webpack_nonce__ = btoa(getRequestToken()) +__webpack_nonce__ = getCSPNonce() if (loadState('comments', 'activityEnabled', false) && OCA?.Activity?.registerSidebarAction !== undefined) { // Do not mount own tab but mount into activity diff --git a/apps/comments/src/components/Comment.vue b/apps/comments/src/components/Comment.vue index 912eeb28748..80f035530fb 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 --> @@ -40,22 +23,27 @@ show if we have a message id and current user is author --> <NcActions v-if="isOwnComment && id && !loading" class="comment__actions"> <template v-if="!editing"> - <NcActionButton :close-after-click="true" - icon="icon-rename" + <NcActionButton close-after-click @click="onEdit"> + <template #icon> + <IconPencilOutline :size="20" /> + </template> {{ t('comments', 'Edit comment') }} </NcActionButton> <NcActionSeparator /> - <NcActionButton :close-after-click="true" - icon="icon-delete" + <NcActionButton close-after-click @click="onDeleteWithUndo"> + <template #icon> + <IconTrashCanOutline :size="20" /> + </template> {{ t('comments', 'Delete comment') }} </NcActionButton> </template> - <NcActionButton v-else - icon="icon-close" - @click="onEditCancel"> + <NcActionButton v-else @click="onEditCancel"> + <template #icon> + <IconClose :size="20" /> + </template> {{ t('comments', 'Cancel edit') }} </NcActionButton> </NcActions> @@ -90,8 +78,8 @@ :disabled="isEmptyMessage" @click="onSubmit"> <template #icon> - <span v-if="loading" class="icon-loading-small" /> - <ArrowRight v-else :size="20" /> + <NcLoadingIcon v-if="loading" /> + <IconArrowRight v-else :size="20" /> </template> </NcButton> </div> @@ -102,14 +90,12 @@ </form> <!-- Message content --> - <!-- The html is escaped and sanitized before rendering --> - <!-- eslint-disable vue/no-v-html--> - <div v-else - :class="{'comment__message--expanded': expanded}" + <NcRichText v-else class="comment__message" - @click="onExpand" - v-html="renderedContent" /> - <!-- eslint-enable vue/no-v-html--> + :class="{'comment__message--expanded': expanded}" + :text="richContent.message" + :arguments="richContent.mentions" + @click="onExpand" /> </div> </component> </template> @@ -118,34 +104,47 @@ import { getCurrentUser } from '@nextcloud/auth' import { translate as t } from '@nextcloud/l10n' -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 RichEditorMixin from '@nextcloud/vue/dist/Mixins/richEditor.js' -import ArrowRight from 'vue-material-design-icons/ArrowRight.vue' +import NcActionButton from '@nextcloud/vue/components/NcActionButton' +import NcActions from '@nextcloud/vue/components/NcActions' +import NcActionSeparator from '@nextcloud/vue/components/NcActionSeparator' +import NcAvatar from '@nextcloud/vue/components/NcAvatar' +import NcButton from '@nextcloud/vue/components/NcButton' +import NcDateTime from '@nextcloud/vue/components/NcDateTime' +import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon' +import NcUserBubble from '@nextcloud/vue/components/NcUserBubble' + +import IconArrowRight from 'vue-material-design-icons/ArrowRight.vue' +import IconClose from 'vue-material-design-icons/Close.vue' +import IconTrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue' +import IconPencilOutline from 'vue-material-design-icons/PencilOutline.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') +const NcRichContenteditable = () => import('@nextcloud/vue/components/NcRichContenteditable') +const NcRichText = () => import('@nextcloud/vue/components/NcRichText') export default { name: 'Comment', components: { - ArrowRight, + IconArrowRight, + IconClose, + IconTrashCanOutline, + IconPencilOutline, NcActionButton, NcActions, NcActionSeparator, NcAvatar, NcButton, NcDateTime, + NcLoadingIcon, NcRichContenteditable, + NcRichText, }, - mixins: [RichEditorMixin, CommentMixin], + mixins: [CommentMixin], inheritAttrs: false, @@ -178,6 +177,10 @@ export default { type: Function, required: true, }, + userData: { + type: Object, + default: () => ({}), + }, tag: { type: String, @@ -196,6 +199,7 @@ export default { }, computed: { + ...mapStores(useDeletedCommentLimbo), /** * Is the current user the author of this comment @@ -206,16 +210,25 @@ export default { return getCurrentUser().uid === this.actorId }, - /** - * Rendered content as html string - * - * @return {string} - */ - renderedContent() { - if (this.isEmptyMessage) { - return '' - } - return this.renderContent(this.localMessage) + richContent() { + const mentions = {} + let message = this.localMessage + + Object.keys(this.userData).forEach((user, index) => { + const key = `mention-${index}` + const regex = new RegExp(`@${user}|@"${user}"`, 'g') + message = message.replace(regex, `{${key}}`) + mentions[key] = { + component: NcUserBubble, + props: { + user, + displayName: this.userData[user].label, + primary: this.userData[user].primary, + }, + } + }) + + return { mentions, message } }, isEmptyMessage() { @@ -228,6 +241,10 @@ export default { timestamp() { return Date.parse(this.creationDateTime) }, + + isLimbo() { + return this.deletedCommentLimboStore.checkForId(this.id) + }, }, watch: { @@ -312,7 +329,7 @@ $comment-padding: 10px; } &__actions { - margin-left: $comment-padding !important; + margin-inline-start: $comment-padding !important; } &__author { @@ -324,8 +341,8 @@ $comment-padding: 10px; &_loading, &__timestamp { - margin-left: auto; - text-align: right; + margin-inline-start: auto; + text-align: end; white-space: nowrap; color: var(--color-text-maxcontrast); } @@ -341,13 +358,13 @@ $comment-padding: 10px; &__submit { position: absolute !important; - bottom: 0; - right: 0; + bottom: 5px; + inset-inline-end: 0; } &__message { white-space: pre-wrap; - word-break: break-word; + word-break: normal; max-height: 70px; overflow: hidden; margin-top: -6px; diff --git a/apps/comments/src/init.ts b/apps/comments/src/init.ts index 448720d34d2..675274b1b40 100644 --- a/apps/comments/src/init.ts +++ b/apps/comments/src/init.ts @@ -1,23 +1,6 @@ /** - * @copyright Copyright (c) 2023 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: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ import { registerFileAction } from '@nextcloud/files' import { action } from './actions/inlineUnreadCommentsAction' diff --git a/apps/comments/src/logger.js b/apps/comments/src/logger.js index d96e85dd92e..a51bc6d750b 100644 --- a/apps/comments/src/logger.js +++ b/apps/comments/src/logger.js @@ -1,23 +1,6 @@ /** - * @copyright Copyright (c) 2023 Lucas Azevedo <lhs_azevedo@hotmail.com> - * - * @author Lucas Azevedo <lhs_azevedo@hotmail.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: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ import { getLoggerBuilder } from '@nextcloud/logger' 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/mixins/CommentView.ts b/apps/comments/src/mixins/CommentView.ts index a49e33f7fd5..c6cb3aa9ee0 100644 --- a/apps/comments/src/mixins/CommentView.ts +++ b/apps/comments/src/mixins/CommentView.ts @@ -1,3 +1,7 @@ +/** + * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ import axios from '@nextcloud/axios' import { getCurrentUser } from '@nextcloud/auth' import { loadState } from '@nextcloud/initial-state' 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/services/DavClient.js b/apps/comments/src/services/DavClient.js index 78bc056357e..3e9a529283f 100644 --- a/apps/comments/src/services/DavClient.js +++ b/apps/comments/src/services/DavClient.js @@ -1,23 +1,6 @@ /** - * @copyright Copyright (c) 2021 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: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ import { createClient } from 'webdav' @@ -29,12 +12,12 @@ const client = createClient(getRootPath()) // set CSRF token header const setHeaders = (token) => { - client.setHeaders({ - // Add this so the server knows it is an request from the browser - 'X-Requested-With': 'XMLHttpRequest', - // Inject user auth - requesttoken: token ?? '', - }) + client.setHeaders({ + // Add this so the server knows it is an request from the browser + 'X-Requested-With': 'XMLHttpRequest', + // Inject user auth + requesttoken: token ?? '', + }) } // refresh headers when request token changes diff --git a/apps/comments/src/services/DeleteComment.js b/apps/comments/src/services/DeleteComment.js index ecfc0fe8b65..1ed63d7836a 100644 --- a/apps/comments/src/services/DeleteComment.js +++ b/apps/comments/src/services/DeleteComment.js @@ -1,23 +1,6 @@ /** - * @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 client from './DavClient.js' diff --git a/apps/comments/src/services/EditComment.js b/apps/comments/src/services/EditComment.js index 1462e99d1db..4ec33415a72 100644 --- a/apps/comments/src/services/EditComment.js +++ b/apps/comments/src/services/EditComment.js @@ -1,23 +1,6 @@ /** - * @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 client from './DavClient.js' diff --git a/apps/comments/src/services/GetComments.ts b/apps/comments/src/services/GetComments.ts index 0736632192d..c42aa21d6cb 100644 --- a/apps/comments/src/services/GetComments.ts +++ b/apps/comments/src/services/GetComments.ts @@ -1,23 +1,6 @@ /** - * @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 { parseXML, type DAVResult, type FileStat, type ResponseDataDetailed } from 'webdav' @@ -77,7 +60,7 @@ const getDirectoryFiles = function( // Map all items to a consistent output structure (results) return responseItems.map(item => { // Each item should contain a stat object - const props = item.propstat!.prop!; + const props = item.propstat!.prop! return prepareFileFromProps(props, props.id!.toString(), isDetailed) }) diff --git a/apps/comments/src/services/NewComment.js b/apps/comments/src/services/NewComment.js index e82f25efe2a..663b4d72e02 100644 --- a/apps/comments/src/services/NewComment.js +++ b/apps/comments/src/services/NewComment.js @@ -1,23 +1,6 @@ /** - * @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 { getCurrentUser } from '@nextcloud/auth' diff --git a/apps/comments/src/services/ReadComments.ts b/apps/comments/src/services/ReadComments.ts index ff29026098a..73682e21d95 100644 --- a/apps/comments/src/services/ReadComments.ts +++ b/apps/comments/src/services/ReadComments.ts @@ -1,23 +1,6 @@ /** - * @copyright 2023 Christopher Ng <chrng8@gmail.com> - * - * @author Christopher Ng <chrng8@gmail.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: 2023 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ import client from './DavClient.js' 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) + }, + }, +}) diff --git a/apps/comments/src/utils/cancelableRequest.js b/apps/comments/src/utils/cancelableRequest.js index 1973de38903..c2d380c80f9 100644 --- a/apps/comments/src/utils/cancelableRequest.js +++ b/apps/comments/src/utils/cancelableRequest.js @@ -1,23 +1,6 @@ /** - * @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 */ /** @@ -39,7 +22,7 @@ const cancelableRequest = function(request) { const fetch = async function(url, options) { const response = await request( url, - Object.assign({ signal }, options) + Object.assign({ signal }, options), ) return response } diff --git a/apps/comments/src/utils/davUtils.js b/apps/comments/src/utils/davUtils.js index 1a2686bbdab..33efc8e7d10 100644 --- a/apps/comments/src/utils/davUtils.js +++ b/apps/comments/src/utils/davUtils.js @@ -1,23 +1,6 @@ /** - * @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 { generateRemoteUrl } from '@nextcloud/router' diff --git a/apps/comments/src/utils/decodeHtmlEntities.js b/apps/comments/src/utils/decodeHtmlEntities.js index 60c08163faa..4c492954256 100644 --- a/apps/comments/src/utils/decodeHtmlEntities.js +++ b/apps/comments/src/utils/decodeHtmlEntities.js @@ -1,23 +1,6 @@ /** - * @copyright Copyright (c) 2021 Christopher Ng <chrng8@gmail.com> - * - * @author Christopher Ng <chrng8@gmail.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: 2021 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later */ /** diff --git a/apps/comments/src/views/ActivityCommentAction.vue b/apps/comments/src/views/ActivityCommentAction.vue index 1bdeca883f7..f9a9a97796f 100644 --- a/apps/comments/src/views/ActivityCommentAction.vue +++ b/apps/comments/src/views/ActivityCommentAction.vue @@ -1,24 +1,7 @@ <!-- - - @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 +--> <template> <Comment v-bind="editorData" diff --git a/apps/comments/src/views/ActivityCommentEntry.vue b/apps/comments/src/views/ActivityCommentEntry.vue index 38fc2d5f1ef..bbfe530b2e3 100644 --- a/apps/comments/src/views/ActivityCommentEntry.vue +++ b/apps/comments/src/views/ActivityCommentEntry.vue @@ -1,24 +1,7 @@ <!-- - - @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 +--> <template> <Comment ref="comment" @@ -34,6 +17,7 @@ </template> <script lang="ts"> +import type { PropType } from 'vue' import { translate as t } from '@nextcloud/l10n' import Comment from '../components/Comment.vue' @@ -53,7 +37,7 @@ export default { required: true, }, reloadCallback: { - type: Function, + type: Function as PropType<() => void>, required: true, }, }, diff --git a/apps/comments/src/views/Comments.vue b/apps/comments/src/views/Comments.vue index f6fb4387596..657af888a12 100644 --- a/apps/comments/src/views/Comments.vue +++ b/apps/comments/src/views/Comments.vue @@ -1,25 +1,7 @@ <!-- - - @copyright Copyright (c) 2020 John Molakvoæ <skjnldsv@protonmail.com> - - - - @author John Molakvoæ <skjnldsv@protonmail.com> - - @author Richard Steinmetz <richard@steinmetz.cloud> - - - - @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> <div v-element-visibility="onVisibilityChange" @@ -40,7 +22,7 @@ class="comments__empty" :name="t('comments', 'No comments yet, start the conversation!')"> <template #icon> - <MessageReplyTextIcon /> + <IconMessageReplyTextOutline /> </template> </NcEmptyContent> <ul v-else> @@ -69,12 +51,12 @@ <template v-else-if="error"> <NcEmptyContent class="comments__error" :name="error"> <template #icon> - <AlertCircleOutlineIcon /> + <IconAlertCircleOutline /> </template> </NcEmptyContent> <NcButton class="comments__retry" @click="getComments"> <template #icon> - <RefreshIcon /> + <IconRefresh /> </template> {{ t('comments', 'Retry') }} </NcButton> @@ -88,11 +70,11 @@ import { showError } from '@nextcloud/dialogs' import { translate as t } from '@nextcloud/l10n' import { vElementVisibility as elementVisibility } from '@vueuse/components' -import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js' -import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' -import RefreshIcon from 'vue-material-design-icons/Refresh.vue' -import MessageReplyTextIcon from 'vue-material-design-icons/MessageReplyText.vue' -import AlertCircleOutlineIcon from 'vue-material-design-icons/AlertCircleOutline.vue' +import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent' +import NcButton from '@nextcloud/vue/components/NcButton' +import IconRefresh from 'vue-material-design-icons/Refresh.vue' +import IconMessageReplyTextOutline from 'vue-material-design-icons/MessageReplyTextOutline.vue' +import IconAlertCircleOutline from 'vue-material-design-icons/AlertCircleOutline.vue' import Comment from '../components/Comment.vue' import CommentView from '../mixins/CommentView' @@ -107,9 +89,9 @@ export default { Comment, NcEmptyContent, NcButton, - RefreshIcon, - MessageReplyTextIcon, - AlertCircleOutlineIcon, + IconRefresh, + IconMessageReplyTextOutline, + IconAlertCircleOutline, }, directives: { |