Drop vue-clipboard2 in favour of native Clipboard API to fix copy to clipboardtags/v26.0.0beta2
methods: { | methods: { | ||||
async copyLink() { | async copyLink() { | ||||
try { | try { | ||||
await this.$copyText(this.internalLink) | |||||
await navigator.clipboard.writeText(this.internalLink) | |||||
showSuccess(t('files_sharing', 'Link copied')) | showSuccess(t('files_sharing', 'Link copied')) | ||||
// focus and show the tooltip (note: cannot set ref on NcActionLink) | // focus and show the tooltip (note: cannot set ref on NcActionLink) | ||||
this.$refs.shareEntrySimple.$refs.actionsComponent.$el.focus() | this.$refs.shareEntrySimple.$refs.actionsComponent.$el.focus() |
}, | }, | ||||
async copyLink() { | async copyLink() { | ||||
try { | try { | ||||
await this.$copyText(this.shareLink) | |||||
await navigator.clipboard.writeText(this.shareLink) | |||||
showSuccess(t('files_sharing', 'Link copied')) | showSuccess(t('files_sharing', 'Link copied')) | ||||
// focus and show the tooltip | // focus and show the tooltip | ||||
this.$refs.copyButton.$el.focus() | this.$refs.copyButton.$el.focus() |
*/ | */ | ||||
import Vue from 'vue' | import Vue from 'vue' | ||||
import VueClipboard from 'vue-clipboard2' | |||||
import { translate as t, translatePlural as n } from '@nextcloud/l10n' | import { translate as t, translatePlural as n } from '@nextcloud/l10n' | ||||
import SharingTab from './views/SharingTab.vue' | import SharingTab from './views/SharingTab.vue' | ||||
Vue.prototype.t = t | Vue.prototype.t = t | ||||
Vue.prototype.n = n | Vue.prototype.n = n | ||||
Vue.use(VueClipboard) | |||||
// Init Sharing tab component | // Init Sharing tab component | ||||
const View = Vue.extend(SharingTab) | const View = Vue.extend(SharingTab) |
class="monospaced" | class="monospaced" | ||||
readonly="readonly" | readonly="readonly" | ||||
@focus="selectInput"> | @focus="selectInput"> | ||||
<a ref="clipboardButton" | |||||
<NcButton type="tertiary" | |||||
:title="copyTooltipOptions" | :title="copyTooltipOptions" | ||||
:aria-label="copyTooltipOptions" | :aria-label="copyTooltipOptions" | ||||
v-clipboard:copy="appPassword" | |||||
v-clipboard:success="onCopyPassword" | |||||
v-clipboard:error="onCopyPasswordFailed" | |||||
class="icon icon-clippy" | |||||
@mouseover="hoveringCopyButton = true" | |||||
@mouseleave="hoveringCopyButton = false" /> | |||||
@click="copyPassword"> | |||||
<template #icon> | |||||
<Check v-if="copied" :size="20" /> | |||||
<ContentCopy v-else :size="20" /> | |||||
</template> | |||||
</NcButton> | |||||
<NcButton @click="reset"> | <NcButton @click="reset"> | ||||
{{ t('settings', 'Done') }} | {{ t('settings', 'Done') }} | ||||
</NcButton> | </NcButton> | ||||
import QR from '@chenfengyuan/vue-qrcode' | import QR from '@chenfengyuan/vue-qrcode' | ||||
import { confirmPassword } from '@nextcloud/password-confirmation' | import { confirmPassword } from '@nextcloud/password-confirmation' | ||||
import '@nextcloud/password-confirmation/dist/style.css' | import '@nextcloud/password-confirmation/dist/style.css' | ||||
import { showError } from '@nextcloud/dialogs' | |||||
import { getRootUrl } from '@nextcloud/router' | import { getRootUrl } from '@nextcloud/router' | ||||
import NcButton from '@nextcloud/vue/dist/Components/NcButton' | import NcButton from '@nextcloud/vue/dist/Components/NcButton' | ||||
import Check from 'vue-material-design-icons/Check.vue' | |||||
import ContentCopy from 'vue-material-design-icons/ContentCopy.vue' | |||||
export default { | export default { | ||||
name: 'AuthTokenSetupDialogue', | name: 'AuthTokenSetupDialogue', | ||||
components: { | components: { | ||||
QR, | |||||
Check, | |||||
ContentCopy, | |||||
NcButton, | NcButton, | ||||
QR, | |||||
}, | }, | ||||
props: { | props: { | ||||
add: { | add: { | ||||
deviceName: '', | deviceName: '', | ||||
appPassword: '', | appPassword: '', | ||||
loginName: '', | loginName: '', | ||||
passwordCopied: false, | |||||
copied: false, | |||||
showQR: false, | showQR: false, | ||||
qrUrl: '', | qrUrl: '', | ||||
hoveringCopyButton: false, | |||||
} | } | ||||
}, | }, | ||||
computed: { | computed: { | ||||
copyTooltipOptions() { | copyTooltipOptions() { | ||||
if (this.passwordCopied) { | |||||
if (this.copied) { | |||||
return t('settings', 'Copied!') | return t('settings', 'Copied!') | ||||
} | } | ||||
return t('settings', 'Copy') | return t('settings', 'Copy') | ||||
this.reset() | this.reset() | ||||
}) | }) | ||||
}, | }, | ||||
onCopyPassword() { | |||||
this.passwordCopied = true | |||||
this.$refs.clipboardButton.blur() | |||||
setTimeout(() => { this.passwordCopied = false }, 3000) | |||||
}, | |||||
onCopyPasswordFailed() { | |||||
OC.Notification.showTemporary(t('settings', 'Could not copy app password. Please copy it manually.')) | |||||
async copyPassword() { | |||||
try { | |||||
await navigator.clipboard.writeText(this.appPassword) | |||||
this.copied = true | |||||
} catch (e) { | |||||
this.copied = false | |||||
console.error(e) | |||||
showError(t('settings', 'Could not copy app password. Please copy it manually.')) | |||||
} finally { | |||||
setTimeout(() => { | |||||
this.copied = false | |||||
}, 4000) | |||||
} | |||||
}, | }, | ||||
reset() { | reset() { | ||||
this.adding = false | this.adding = false |
import { loadState } from '@nextcloud/initial-state' | import { loadState } from '@nextcloud/initial-state' | ||||
import Vue from 'vue' | import Vue from 'vue' | ||||
import VueClipboard from 'vue-clipboard2' | |||||
import VTooltip from 'v-tooltip' | import VTooltip from 'v-tooltip' | ||||
import AuthTokenSection from './components/AuthTokenSection' | import AuthTokenSection from './components/AuthTokenSection' | ||||
// eslint-disable-next-line camelcase | // eslint-disable-next-line camelcase | ||||
__webpack_nonce__ = btoa(OC.requestToken) | __webpack_nonce__ = btoa(OC.requestToken) | ||||
Vue.use(VueClipboard) | |||||
Vue.use(VTooltip, { defaultHtml: false }) | Vue.use(VTooltip, { defaultHtml: false }) | ||||
Vue.prototype.t = t | Vue.prototype.t = t | ||||
"v-tooltip": "^2.1.3", | "v-tooltip": "^2.1.3", | ||||
"vue": "^2.7.14", | "vue": "^2.7.14", | ||||
"vue-click-outside": "^1.1.0", | "vue-click-outside": "^1.1.0", | ||||
"vue-clipboard2": "^0.3.3", | |||||
"vue-cropperjs": "^4.2.0", | "vue-cropperjs": "^4.2.0", | ||||
"vue-infinite-loading": "^2.4.5", | "vue-infinite-loading": "^2.4.5", | ||||
"vue-localstorage": "^0.6.2", | "vue-localstorage": "^0.6.2", | ||||
"resolved": "https://registry.npmjs.org/vue-click-outside/-/vue-click-outside-1.1.0.tgz", | "resolved": "https://registry.npmjs.org/vue-click-outside/-/vue-click-outside-1.1.0.tgz", | ||||
"integrity": "sha512-pNyvAA9mRXJwPHlHJyjMb4IONSc7khS5lxGcMyE2EIKgNMAO279PWM9Hyq0d5J4FkiSRdmFLwnbjDd5UtPizHQ==" | "integrity": "sha512-pNyvAA9mRXJwPHlHJyjMb4IONSc7khS5lxGcMyE2EIKgNMAO279PWM9Hyq0d5J4FkiSRdmFLwnbjDd5UtPizHQ==" | ||||
}, | }, | ||||
"node_modules/vue-clipboard2": { | |||||
"version": "0.3.3", | |||||
"resolved": "https://registry.npmjs.org/vue-clipboard2/-/vue-clipboard2-0.3.3.tgz", | |||||
"integrity": "sha512-aNWXIL2DKgJyY/1OOeITwAQz1fHaCIGvUFHf9h8UcoQBG5a74MkdhS/xqoYe7DNZdQmZRL+TAdIbtUs9OyVjbw==", | |||||
"dependencies": { | |||||
"clipboard": "^2.0.0" | |||||
} | |||||
}, | |||||
"node_modules/vue-color": { | "node_modules/vue-color": { | ||||
"version": "2.8.1", | "version": "2.8.1", | ||||
"resolved": "https://registry.npmjs.org/vue-color/-/vue-color-2.8.1.tgz", | "resolved": "https://registry.npmjs.org/vue-color/-/vue-color-2.8.1.tgz", | ||||
"resolved": "https://registry.npmjs.org/vue-click-outside/-/vue-click-outside-1.1.0.tgz", | "resolved": "https://registry.npmjs.org/vue-click-outside/-/vue-click-outside-1.1.0.tgz", | ||||
"integrity": "sha512-pNyvAA9mRXJwPHlHJyjMb4IONSc7khS5lxGcMyE2EIKgNMAO279PWM9Hyq0d5J4FkiSRdmFLwnbjDd5UtPizHQ==" | "integrity": "sha512-pNyvAA9mRXJwPHlHJyjMb4IONSc7khS5lxGcMyE2EIKgNMAO279PWM9Hyq0d5J4FkiSRdmFLwnbjDd5UtPizHQ==" | ||||
}, | }, | ||||
"vue-clipboard2": { | |||||
"version": "0.3.3", | |||||
"resolved": "https://registry.npmjs.org/vue-clipboard2/-/vue-clipboard2-0.3.3.tgz", | |||||
"integrity": "sha512-aNWXIL2DKgJyY/1OOeITwAQz1fHaCIGvUFHf9h8UcoQBG5a74MkdhS/xqoYe7DNZdQmZRL+TAdIbtUs9OyVjbw==", | |||||
"requires": { | |||||
"clipboard": "^2.0.0" | |||||
} | |||||
}, | |||||
"vue-color": { | "vue-color": { | ||||
"version": "2.8.1", | "version": "2.8.1", | ||||
"resolved": "https://registry.npmjs.org/vue-color/-/vue-color-2.8.1.tgz", | "resolved": "https://registry.npmjs.org/vue-color/-/vue-color-2.8.1.tgz", |
"v-tooltip": "^2.1.3", | "v-tooltip": "^2.1.3", | ||||
"vue": "^2.7.14", | "vue": "^2.7.14", | ||||
"vue-click-outside": "^1.1.0", | "vue-click-outside": "^1.1.0", | ||||
"vue-clipboard2": "^0.3.3", | |||||
"vue-cropperjs": "^4.2.0", | "vue-cropperjs": "^4.2.0", | ||||
"vue-infinite-loading": "^2.4.5", | "vue-infinite-loading": "^2.4.5", | ||||
"vue-localstorage": "^0.6.2", | "vue-localstorage": "^0.6.2", |