From f1b9c4d4cae1472bfce565e144f90b068aaa22fb Mon Sep 17 00:00:00 2001 From: "Grigorii K. Shartsev" Date: Wed, 23 Oct 2024 15:11:46 +0200 Subject: [PATCH] feat(chat): add download link to attachments Signed-off-by: Grigorii K. Shartsev --- .../MessageButtonsBar/MessageButtonsBar.vue | 42 ++++++++++++------- src/utils/davUtils.ts | 29 +++++++++++++ 2 files changed, 57 insertions(+), 14 deletions(-) create mode 100644 src/utils/davUtils.ts diff --git a/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue b/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue index ea5e7f050dc..197f2538af7 100644 --- a/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue +++ b/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue @@ -106,13 +106,21 @@ {{ t('spreed', 'Mark as unread') }} - - - {{ t('spreed', 'Go to file') }} - + @@ -260,6 +268,7 @@ import ClockOutline from 'vue-material-design-icons/ClockOutline.vue' import CloseCircleOutline from 'vue-material-design-icons/CloseCircleOutline.vue' import ContentCopy from 'vue-material-design-icons/ContentCopy.vue' import DeleteIcon from 'vue-material-design-icons/Delete.vue' +import IconDownload from 'vue-material-design-icons/Download.vue' import EmoticonOutline from 'vue-material-design-icons/EmoticonOutline.vue' import EyeOffOutline from 'vue-material-design-icons/EyeOffOutline.vue' import File from 'vue-material-design-icons/File.vue' @@ -271,6 +280,7 @@ import Reply from 'vue-material-design-icons/Reply.vue' import Share from 'vue-material-design-icons/Share.vue' import Translate from 'vue-material-design-icons/Translate.vue' +import { getCurrentUser } from '@nextcloud/auth' import { showError, showSuccess } from '@nextcloud/dialogs' import { t } from '@nextcloud/l10n' import moment from '@nextcloud/moment' @@ -291,6 +301,7 @@ import { hasTalkFeature } from '../../../../../services/CapabilitiesManager.ts' import { getMessageReminder, removeMessageReminder, setMessageReminder } from '../../../../../services/remindersService.js' import { useIntegrationsStore } from '../../../../../stores/integrations.js' import { useReactionsStore } from '../../../../../stores/reactions.js' +import { generatePublicShareDownloadUrl, generateUserFileUrl } from '../../../../../utils/davUtils.ts' import { copyConversationLinkToClipboard } from '../../../../../utils/handleUrl.ts' import { parseMentions } from '../../../../../utils/textParse.ts' @@ -317,6 +328,7 @@ export default { ClockEditOutline, ClockOutline, ContentCopy, + IconDownload, DeleteIcon, EmoticonOutline, EyeOffOutline, @@ -438,13 +450,15 @@ export default { && this.$store.getters.isActorUser() }, - linkToFile() { - if (this.isFileShare) { - const firstFileKey = (Object.keys(this.message.messageParameters).find(key => key.startsWith('file'))) - return this.message.messageParameters?.[firstFileKey]?.link - } else { - return '' - } + messageFile() { + const firstFileKey = (Object.keys(this.message.messageParameters).find(key => key.startsWith('file'))) + return this.message.messageParameters[firstFileKey] + }, + + linkToFileDownload() { + return getCurrentUser() + ? generateUserFileUrl(this.messageFile.path) + : generatePublicShareDownloadUrl(this.messageFile.link) }, isCurrentGuest() { diff --git a/src/utils/davUtils.ts b/src/utils/davUtils.ts new file mode 100644 index 00000000000..eaf2690f678 --- /dev/null +++ b/src/utils/davUtils.ts @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { getCurrentUser } from '@nextcloud/auth' +import { davRemoteURL } from '@nextcloud/files' + +/** + * Generate a WebDAV url to a user files + * @param filepath - The path to the user's file, e.g., Talk/20240101-000102.png + * @param userid - The user id, e.g., 'admin'. Defaults to the current user id + * @return {string} The WebDAV URL to the file, e.g., https://nextcloud.ltd/remote.php/dav/files/admin/Talk/20240101-000102.png + */ +export function generateUserFileUrl(filepath: string, userid: string | undefined = getCurrentUser()?.uid) { + if (!userid) { + throw new TypeError('Cannot generate /files// URL without a user') + } + return davRemoteURL + '/files/' + encodeURI(userid) + '/' + encodeURI(filepath) +} + +/** + * Generate a download link for a public share + * @param shareLink - The public share link, e.g., https://nextcloud.ltd/s/CBeNTiJz5JeT2CH/ + * @return {string} The download link, e.g., https://nextcloud.ltd/s/CBeNTiJz5JeT2CH/download + */ +export function generatePublicShareDownloadUrl(shareLink: string) { + return shareLink + '/download' +}