summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigorii Shartsev <grigorii.shartsev@nextcloud.com>2023-03-12 21:12:39 +0100
committerGrigorii Shartsev <grigorii.shartsev@nextcloud.com>2023-03-21 15:10:00 +0100
commit3603b566bc5bab03b60f7361a3a7abb97bd4be1b (patch)
tree41ededd34645623862b33fed4c706de5f6f9a48d
parent6d887a87a749efbcd0d080f7b3d6e5ef22f27649 (diff)
feat: add utils for generating absolute links and copy a chat link
- Add `generateAbsoluteUrl` util - Add `copyLinkToConversation` method for copying conversation links to the clipboard with dialogs - Remove unused - Use dialogs on new conversation confirmation Signed-off-by: Grigorii Shartsev <grigorii.shartsev@nextcloud.com>
-rw-r--r--src/components/CallView/shared/EmptyCallView.vue24
-rw-r--r--src/components/ConversationSettings/LinkShareSettings.vue13
-rw-r--r--src/components/LeftSidebar/ConversationsList/Conversation.vue23
-rw-r--r--src/components/LeftSidebar/NewGroupConversation/Confirmation/Confirmation.vue52
-rw-r--r--src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue15
-rw-r--r--src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue13
-rw-r--r--src/components/TopBar/TopBar.vue9
-rw-r--r--src/components/TopBar/TopBarMenu.vue4
-rw-r--r--src/services/urlService.js76
9 files changed, 113 insertions, 116 deletions
diff --git a/src/components/CallView/shared/EmptyCallView.vue b/src/components/CallView/shared/EmptyCallView.vue
index 662773910..81e2028a8 100644
--- a/src/components/CallView/shared/EmptyCallView.vue
+++ b/src/components/CallView/shared/EmptyCallView.vue
@@ -29,19 +29,17 @@
</p>
<NcButton v-if="showLink"
type="primary"
- @click.stop.prevent="copyLinkToConversation">
+ @click.stop.prevent="handleCopyLink">
{{ t('spreed', 'Copy link') }}
</NcButton>
</div>
</template>
<script>
-import { showError, showSuccess } from '@nextcloud/dialogs'
-import { generateUrl } from '@nextcloud/router'
-
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import { CONVERSATION, PARTICIPANT } from '../../../constants.js'
+import { copyLinkToConversation } from '../../../services/urlService.js'
export default {
@@ -161,24 +159,13 @@ export default {
showLink() {
return this.isPublicConversation && !this.isPasswordRequestConversation && !this.isFileConversation
},
-
- linkToConversation() {
- return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + this.token)
- },
-
},
methods: {
- async copyLinkToConversation() {
- try {
- await navigator.clipboard.writeText(this.linkToConversation)
- showSuccess(t('spreed', 'Conversation link copied to clipboard'))
- } catch (error) {
- showError(t('spreed', 'The link could not be copied'))
- }
+ async handleCopyLink() {
+ await copyLinkToConversation(this.token)
},
},
-
}
</script>
@@ -201,12 +188,13 @@ export default {
width: 64px;
margin: 0 auto 15px;
}
+
button {
margin: 4px auto;
}
h2, p {
- color: #ffffff;
+ color: #FFFFFF;
}
&--sidebar {
diff --git a/src/components/ConversationSettings/LinkShareSettings.vue b/src/components/ConversationSettings/LinkShareSettings.vue
index cc67af8e7..023549d5c 100644
--- a/src/components/ConversationSettings/LinkShareSettings.vue
+++ b/src/components/ConversationSettings/LinkShareSettings.vue
@@ -98,13 +98,13 @@ import ClipboardTextOutline from 'vue-material-design-icons/ClipboardTextOutline
import Email from 'vue-material-design-icons/Email.vue'
import { showError, showSuccess } from '@nextcloud/dialogs'
-import { generateUrl } from '@nextcloud/router'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcPasswordField from '@nextcloud/vue/dist/Components/NcPasswordField.js'
import { CONVERSATION } from '../../constants.js'
+import { copyLinkToConversation } from '../../services/urlService.js'
export default {
name: 'LinkShareSettings',
@@ -142,10 +142,6 @@ export default {
conversation() {
return this.$store.getters.conversation(this.token) || this.$store.getters.dummyConversation
},
-
- linkToConversation() {
- return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + this.token)
- },
},
methods: {
@@ -236,12 +232,7 @@ export default {
},
async handleCopyLink() {
- try {
- await navigator.clipboard.writeText(this.linkToConversation)
- showSuccess(t('spreed', 'Conversation link copied to clipboard.'))
- } catch (error) {
- showError(t('spreed', 'The link could not be copied.'))
- }
+ await copyLinkToConversation(this.token)
},
async handleResendInvitations() {
diff --git a/src/components/LeftSidebar/ConversationsList/Conversation.vue b/src/components/LeftSidebar/ConversationsList/Conversation.vue
index 6f36d8fc8..afdfc5ca9 100644
--- a/src/components/LeftSidebar/ConversationsList/Conversation.vue
+++ b/src/components/LeftSidebar/ConversationsList/Conversation.vue
@@ -59,7 +59,7 @@
{{ labelFavorite }}
</NcActionButton>
<NcActionButton icon="icon-clippy"
- @click.stop.prevent="copyLinkToConversation">
+ @click.stop.prevent="handleCopyLink">
{{ t('spreed', 'Copy link') }}
</NcActionButton>
<NcActionButton :close-after-click="true"
@@ -106,9 +106,8 @@ import ExitToApp from 'vue-material-design-icons/ExitToApp.vue'
import EyeOutline from 'vue-material-design-icons/EyeOutline.vue'
import Star from 'vue-material-design-icons/Star.vue'
-import { showError, showSuccess } from '@nextcloud/dialogs'
+import { showError } from '@nextcloud/dialogs'
import { emit } from '@nextcloud/event-bus'
-import { generateUrl } from '@nextcloud/router'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js'
@@ -116,9 +115,11 @@ import NcListItem from '@nextcloud/vue/dist/Components/NcListItem.js'
import ConversationIcon from './../../ConversationIcon.vue'
import { CONVERSATION, PARTICIPANT, ATTENDEE } from '../../../constants.js'
+import { copyLinkToConversation } from '../../../services/urlService.js'
export default {
name: 'Conversation',
+
components: {
Cog,
ConversationIcon,
@@ -129,6 +130,7 @@ export default {
NcListItem,
Star,
},
+
props: {
isSearchResult: {
type: Boolean,
@@ -155,7 +157,6 @@ export default {
},
computed: {
-
counterType() {
if (this.item.unreadMentionDirect || (this.item.unreadMessages !== 0 && (
this.item.type === CONVERSATION.TYPE.ONE_TO_ONE || this.item.type === CONVERSATION.TYPE.ONE_TO_ONE_FORMER
@@ -168,10 +169,6 @@ export default {
}
},
- linkToConversation() {
- return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + this.item.token)
- },
-
canFavorite() {
return this.item.participantType !== PARTICIPANT.TYPE.USER_SELF_JOINED
},
@@ -331,14 +328,8 @@ export default {
},
methods: {
- async copyLinkToConversation() {
- try {
- await navigator.clipboard.writeText(this.linkToConversation)
- showSuccess(t('spreed', 'Conversation link copied to clipboard'))
- } catch (error) {
- console.error('Error copying link: ', error)
- showError(t('spreed', 'The link could not be copied'))
- }
+ async handleCopyLink() {
+ await copyLinkToConversation(this.item.token)
},
markConversationAsRead() {
diff --git a/src/components/LeftSidebar/NewGroupConversation/Confirmation/Confirmation.vue b/src/components/LeftSidebar/NewGroupConversation/Confirmation/Confirmation.vue
index e9efb0eac..acf0766c7 100644
--- a/src/components/LeftSidebar/NewGroupConversation/Confirmation/Confirmation.vue
+++ b/src/components/LeftSidebar/NewGroupConversation/Confirmation/Confirmation.vue
@@ -34,15 +34,11 @@
{{ t('spreed', 'All set') }}
</p>
<NcButton id="copy-link"
- slot="trigger"
type="secondary"
class="confirmation__copy-link"
@click="onClickCopyLink">
{{ t('spreed', 'Copy conversation link') }}
</NcButton>
- <p class="confirmation__warning">
- {{ confirmationText }}
- </p>
</template>
</template>
<template v-else>
@@ -57,12 +53,18 @@
<script>
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
+import { copyLinkToConversation } from '../../../../services/urlService.js'
+
export default {
name: 'Confirmation',
components: {
NcButton,
},
props: {
+ token: {
+ type: String,
+ required: true,
+ },
conversationName: {
type: String,
required: true,
@@ -83,42 +85,11 @@ export default {
type: Boolean,
required: true,
},
- linkToConversation: {
- type: String,
- required: true,
- },
- },
-
- data() {
- return {
- showTooltip: false,
- confirmationText: '',
- showConfirmationText: false,
- }
},
methods: {
- async onClickCopyLink() {
- try {
- await navigator.clipboard.writeText(this.linkToConversation)
- this.onCopy()
- } catch (error) {
- this.onError()
- }
- },
- onCopy() {
- this.confirmationText = t('spreed', 'Link copied to the clipboard!')
- this.showConfirmationText = true
- setTimeout(function() {
- this.showConfirmationText = false
- }, 800)
- },
- onError() {
- this.confirmationText = t('spreed', 'Error')
- this.showConfirmationText = true
- setTimeout(function() {
- this.showConfirmationText = false
- }, 800)
+ onClickCopyLink() {
+ copyLinkToConversation(this.token)
},
},
@@ -130,13 +101,16 @@ export default {
.confirmation {
display: flex;
flex-direction: column;
- &__icon{
+
+ &__icon {
padding-top: 80px;
}
- &__warning{
+
+ &__warning {
margin-top: 10px;
text-align: center;
}
+
&__copy-link {
margin: 50px auto 0 auto;
}
diff --git a/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue b/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue
index 326fe08ed..fa4d57a0c 100644
--- a/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue
+++ b/src/components/LeftSidebar/NewGroupConversation/NewGroupConversation.vue
@@ -71,12 +71,12 @@
</template>
<!-- Third page -->
<template v-if="page === 2">
- <Confirmation :conversation-name="conversationName"
+ <Confirmation :token="token"
+ :conversation-name="conversationName"
:error="error"
:is-loading="isLoading"
:success="success"
- :is-public="isPublic"
- :link-to-conversation="linkToConversation" />
+ :is-public="isPublic" />
</template>
</div>
<!-- Navigation: different buttons with different actions and
@@ -125,8 +125,6 @@
import Plus from 'vue-material-design-icons/Plus.vue'
-import { generateUrl } from '@nextcloud/router'
-
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch.js'
import NcModal from '@nextcloud/vue/dist/Components/NcModal.js'
@@ -148,6 +146,7 @@ import {
} from '../../../services/conversationsService.js'
import { EventBus } from '../../../services/EventBus.js'
import { addParticipant } from '../../../services/participantsService.js'
+import { generateFullConversationLink } from '../../../services/urlService.js'
export default {
@@ -198,12 +197,6 @@ export default {
conversationName() {
return this.conversationNameInput.trim()
},
- // Generates the link to the current conversation
- linkToConversation() {
- if (this.token !== '') {
- return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + this.token)
- } else return ''
- },
// Controls the disabled/enabled state of the first page's button.
disabled() {
return this.conversationName === '' || (this.passwordProtect && this.password === '')
diff --git a/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue b/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue
index d32bb6412..76bba8531 100644
--- a/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue
+++ b/src/components/MessagesList/MessagesGroup/Message/MessageButtonsBar/MessageButtonsBar.vue
@@ -169,9 +169,7 @@ import Plus from 'vue-material-design-icons/Plus.vue'
import Reply from 'vue-material-design-icons/Reply.vue'
import Share from 'vue-material-design-icons/Share.vue'
-import { showError, showSuccess } from '@nextcloud/dialogs'
import moment from '@nextcloud/moment'
-import { generateUrl } from '@nextcloud/router'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
@@ -184,6 +182,7 @@ import Forwarder from './Forwarder.vue'
import { PARTICIPANT, CONVERSATION, ATTENDEE } from '../../../../../constants.js'
import { EventBus } from '../../../../../services/EventBus.js'
+import { copyLinkToConversation } from '../../../../../services/urlService.js'
// Keep version in sync with @nextcloud/vue in case of issues
@@ -212,6 +211,7 @@ export default {
Reply,
Share,
},
+
props: {
token: {
type: String,
@@ -469,14 +469,7 @@ export default {
},
async handleCopyMessageLink() {
- try {
- const link = window.location.protocol + '//' + window.location.host + generateUrl('/call/' + this.token) + '#message_' + this.id
- await navigator.clipboard.writeText(link)
- showSuccess(t('spreed', 'Message link copied to clipboard'))
- } catch (error) {
- console.error('Error copying link: ', error)
- showError(t('spreed', 'The link could not be copied'))
- }
+ await copyLinkToConversation(this.token, this.id)
},
async handleMarkAsUnread() {
diff --git a/src/components/TopBar/TopBar.vue b/src/components/TopBar/TopBar.vue
index 025dc2abc..f1480ad8f 100644
--- a/src/components/TopBar/TopBar.vue
+++ b/src/components/TopBar/TopBar.vue
@@ -136,7 +136,6 @@ import MessageText from 'vue-material-design-icons/MessageText.vue'
import { showMessage } from '@nextcloud/dialogs'
import { emit } from '@nextcloud/event-bus'
-import { generateUrl } from '@nextcloud/router'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js'
@@ -245,14 +244,6 @@ export default {
return this.conversation.unreadMention
},
- linkToConversation() {
- if (this.token !== '') {
- return window.location.protocol + '//' + window.location.host + generateUrl('/call/' + this.token)
- } else {
- return ''
- }
- },
-
renderedDescription() {
return this.renderContent(this.conversation.description)
},
diff --git a/src/components/TopBar/TopBarMenu.vue b/src/components/TopBar/TopBarMenu.vue
index 53bcd34e4..376c50a46 100644
--- a/src/components/TopBar/TopBarMenu.vue
+++ b/src/components/TopBar/TopBarMenu.vue
@@ -170,7 +170,6 @@ import VideoIcon from 'vue-material-design-icons/Video.vue'
import { getCapabilities } from '@nextcloud/capabilities'
import { emit } from '@nextcloud/event-bus'
-import { generateUrl } from '@nextcloud/router'
import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
import NcActionLink from '@nextcloud/vue/dist/Components/NcActionLink.js'
@@ -183,6 +182,7 @@ import PromotedView from '../missingMaterialDesignIcons/PromotedView.vue'
import { CALL, CONVERSATION, PARTICIPANT } from '../../constants.js'
import isInCall from '../../mixins/isInCall.js'
+import { generateAbsoluteUrl } from '../../services/urlService.js'
import { callParticipantCollection } from '../../utils/webrtc/index.js'
export default {
@@ -280,7 +280,7 @@ export default {
linkToFile() {
if (this.isFileConversation) {
- return window.location.protocol + '//' + window.location.host + generateUrl('/f/' + this.conversation.objectId)
+ return generateAbsoluteUrl('/f/{objectId}', { objectId: this.conversation.objectId })
} else {
return ''
}
diff --git a/src/services/urlService.js b/src/services/urlService.js
new file mode 100644
index 000000000..3b9dd6cda
--- /dev/null
+++ b/src/services/urlService.js
@@ -0,0 +1,76 @@
+/*
+ * @copyright Copyright (c) 2023 Grigorii Shartsev <grigorii.shartsev@nextcloud.com>
+ *
+ * @author Grigorii Shartsev <grigorii.shartsev@nextcloud.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/>.
+ */
+
+import { showError, showSuccess } from '@nextcloud/dialogs'
+import { generateUrl } from '@nextcloud/router'
+
+/**
+ * Generate a full absolute link with @nextcloud/router.generateUrl
+ *
+ * @see @nextcloud/router.generateUrl
+ * @param {string} url
+ * @param {object} [params] parameters to be replaced into the address
+ * @param {import('@nextcloud/router').UrlOptions} [options] options for the parameter replacement
+ * @param {boolean} options.noRewrite True if you want to force index.php being added
+ * @param {boolean} options.escape Set to false if parameters should not be URL encoded (default true)
+ * @return {string} Full absolute URL
+ */
+export function generateAbsoluteUrl(url, params, options) {
+ // TODO: add this function to @nextcloud/router?
+ const fullPath = generateUrl(url, params, options)
+ if (!IS_DESKTOP) {
+ return `${window.location.protocol}//${window.location.host}${fullPath}`
+ } else {
+ return fullPath
+ }
+}
+
+/**
+ * Generate full link to conversation
+ *
+ * @param {string} token - Conversation token
+ * @param {string} [messageId] - messageId for message in conversation link
+ * @return {string} - Absolute URL to conversation
+ */
+export function generateFullConversationLink(token, messageId) {
+ return messageId !== undefined
+ ? generateAbsoluteUrl('/call/{token}#message_{messageId}', {
+ token,
+ messageId,
+ })
+ : generateAbsoluteUrl('/call/{token}', { token })
+}
+
+/**
+ * Try to copy conversation link to a clipboard and display the result with dialogs
+ *
+ * @param {string} token - conversation token
+ * @param {string} [messageId] - messageId for message in conversation link
+ * @return {Promise<void>}
+ */
+export async function copyLinkToConversation(token, messageId) {
+ try {
+ await navigator.clipboard.writeText(generateFullConversationLink(token, messageId))
+ showSuccess(t('spreed', 'Conversation link copied to clipboard'))
+ } catch (error) {
+ showError(t('spreed', 'The link could not be copied'))
+ }
+}