Cleaning up calls to the Clipboard API (#2597)

* Added a copyToClipboard function to utils

This should make it easier to handle errors which
result from the clipboard API (which are more likely
in web builds). This should also make it easier to handle
copying to clipboard in cordova builds by abstracting the
platform specific code out of the views and moving it
all into one function.

* Moved the $t function out of utils

* Removing locale snippets I was using and am not now

* Added function comment to copyToClipboard

* Adding some missing references

* Adding an additional check

* Re-reviewing my changes, I found a mistake

* Update src/renderer/store/modules/utils.js

Co-authored-by: absidue <48293849+absidue@users.noreply.github.com>

* Update static/locales/en-US.yaml

Co-authored-by: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com>

* Reverting the language back to what it was previously

* Switching to using i18n.t()

instead of handling the translations myself.
Also, it looks like eslint removed a tab.

Co-authored-by: absidue <48293849+absidue@users.noreply.github.com>
Co-authored-by: ChunkyProgrammer <78101139+ChunkyProgrammer@users.noreply.github.com>
This commit is contained in:
Emma 2022-09-21 03:00:21 -04:00 committed by GitHub
parent b722435a88
commit 25d954f990
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 106 additions and 89 deletions

View File

@ -1291,7 +1291,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err.responseJSON.error}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err.responseJSON.error)
this.copyToClipboard({ content: err.responseJSON.error })
}
})
@ -1318,7 +1318,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
@ -1348,7 +1348,8 @@ export default Vue.extend({
'showSaveDialog',
'getUserDataPath',
'addPlaylist',
'addVideo'
'addVideo',
'copyToClipboard'
]),
...mapMutations([

View File

@ -303,46 +303,31 @@ export default Vue.extend({
}
break
case 'copyYoutube':
navigator.clipboard.writeText(this.youtubeShareUrl)
this.showToast({
message: this.$t('Share.YouTube URL copied to clipboard')
})
this.copyToClipboard({ content: this.youtubeShareUrl, messageOnSuccess: this.$t('Share.YouTube URL copied to clipboard') })
break
case 'openYoutube':
this.openExternalLink(this.youtubeUrl)
break
case 'copyYoutubeEmbed':
navigator.clipboard.writeText(this.youtubeEmbedUrl)
this.showToast({
message: this.$t('Share.YouTube Embed URL copied to clipboard')
})
this.copyToClipboard({ content: this.youtubeEmbedUrl, messageOnSuccess: this.$t('Share.YouTube Embed URL copied to clipboard') })
break
case 'openYoutubeEmbed':
this.openExternalLink(this.youtubeEmbedUrl)
break
case 'copyInvidious':
navigator.clipboard.writeText(this.invidiousUrl)
this.showToast({
message: this.$t('Share.Invidious URL copied to clipboard')
})
this.copyToClipboard({ content: this.invidiousUrl, messageOnSuccess: this.$t('Share.Invidious URL copied to clipboard') })
break
case 'openInvidious':
this.openExternalLink(this.invidiousUrl)
break
case 'copyYoutubeChannel':
navigator.clipboard.writeText(this.youtubeChannelUrl)
this.showToast({
message: this.$t('Share.YouTube Channel URL copied to clipboard')
})
this.copyToClipboard({ content: this.youtubeChannelUrl, messageOnSuccess: this.$t('Share.YouTube Channel URL copied to clipboard') })
break
case 'openYoutubeChannel':
this.openExternalLink(this.youtubeChannelUrl)
break
case 'copyInvidiousChannel':
navigator.clipboard.writeText(this.invidiousChannelUrl)
this.showToast({
message: this.$t('Share.Invidious Channel URL copied to clipboard')
})
this.copyToClipboard({ content: this.invidiousChannelUrl, messageOnSuccess: this.$t('Share.Invidious Channel URL copied to clipboard') })
break
case 'openInvidiousChannel':
this.openExternalLink(this.invidiousChannelUrl)
@ -540,7 +525,8 @@ export default Vue.extend({
'removeFromHistory',
'addVideo',
'removeVideo',
'openExternalLink'
'openExternalLink',
'copyToClipboard'
])
}
})

View File

@ -76,9 +76,6 @@ export default Vue.extend({
}
},
methods: {
copy(text) {
navigator.clipboard.writeText(text)
},
openInvidious() {
this.openExternalLink(this.getFinalUrl(this.invidiousURL))
@ -86,10 +83,7 @@ export default Vue.extend({
},
copyInvidious() {
this.showToast({
message: this.$t('Share.Invidious URL copied to clipboard')
})
this.copy(this.getFinalUrl(this.invidiousURL))
this.copyToClipboard({ content: this.getFinalUrl(this.invidiousURL), messageOnSuccess: this.$t('Share.Invidious URL copied to clipboard') })
this.$refs.iconButton.focusOut()
},
@ -99,10 +93,7 @@ export default Vue.extend({
},
copyYoutube() {
this.showToast({
message: this.$t('Share.YouTube URL copied to clipboard')
})
this.copy(this.getFinalUrl(this.youtubeShareURL))
this.copyToClipboard({ content: this.getFinalUrl(this.youtubeShareURL), messageOnSuccess: this.$t('Share.YouTube URL copied to clipboard') })
this.$refs.iconButton.focusOut()
},
@ -112,10 +103,7 @@ export default Vue.extend({
},
copyYoutubeEmbed() {
this.showToast({
message: this.$t('Share.YouTube Embed URL copied to clipboard')
})
this.copy(this.getFinalUrl(this.youtubeEmbedURL))
this.copyToClipboard({ content: this.getFinalUrl(this.youtubeEmbedURL), messageOnSuccess: this.$t('Share.YouTube Embed URL copied to clipboard') })
this.$refs.iconButton.focusOut()
},
@ -125,10 +113,7 @@ export default Vue.extend({
},
copyInvidiousEmbed() {
this.showToast({
message: this.$t('Share.Invidious Embed URL copied to clipboard')
})
this.copy(this.getFinalUrl(this.invidiousEmbedURL))
this.copyToClipboard({ content: this.getFinalUrl(this.invidiousEmbedURL), messageOnSuccess: this.$t('Share.Invidious Embed URL copied to clipboard') })
this.$refs.iconButton.focusOut()
},
@ -145,7 +130,8 @@ export default Vue.extend({
...mapActions([
'showToast',
'openExternalLink'
'openExternalLink',
'copyToClipboard'
])
}
})

View File

@ -111,19 +111,13 @@ export default Vue.extend({
switch (method) {
case 'copyYoutube':
navigator.clipboard.writeText(youtubeUrl)
this.showToast({
message: this.$t('Share.YouTube URL copied to clipboard')
})
this.copyToClipboard({ content: youtubeUrl, messageOnSuccess: this.$t('Share.YouTube URL copied to clipboard') })
break
case 'openYoutube':
this.openExternalLink(youtubeUrl)
break
case 'copyInvidious':
navigator.clipboard.writeText(invidiousUrl)
this.showToast({
message: this.$t('Share.Invidious URL copied to clipboard')
})
this.copyToClipboard({ content: invidiousUrl, messageOnSuccess: this.$t('Share.Invidious URL copied to clipboard') })
break
case 'openInvidious':
this.openExternalLink(invidiousUrl)
@ -150,7 +144,8 @@ export default Vue.extend({
...mapActions([
'showToast',
'openExternalLink'
'openExternalLink',
'copyToClipboard'
])
}
})

View File

@ -188,7 +188,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendFallback && this.backendPreference === 'local') {
@ -223,7 +223,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendFallback && this.backendPreference === 'local') {
@ -339,7 +339,7 @@ export default Vue.extend({
message: `${errorMessage}: ${xhr.responseText}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(xhr.responseText)
this.copyToClipboard({ content: xhr.responseText })
}
})
if (this.backendFallback && this.backendPreference === 'invidious') {
@ -396,7 +396,7 @@ export default Vue.extend({
message: `${errorMessage}: ${xhr.responseText}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(xhr.responseText)
this.copyToClipboard({ content: xhr.responseText })
}
})
this.isLoading = false
@ -410,7 +410,8 @@ export default Vue.extend({
...mapActions([
'showToast',
'toLocalePublicationString',
'invidiousAPICall'
'invidiousAPICall',
'copyToClipboard'
])
}
})

View File

@ -313,7 +313,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'local' && this.backendFallback) {
@ -354,7 +354,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'invidious' && this.backendFallback) {
@ -392,7 +392,8 @@ export default Vue.extend({
...mapActions([
'showToast',
'ytGetPlaylistInfo',
'invidiousGetPlaylistInfo'
'invidiousGetPlaylistInfo',
'copyToClipboard'
])
}
})

View File

@ -246,6 +246,45 @@ const actions = {
return filenameNew
},
/**
* This writes to the clipboard. If an error occurs during the copy,
* a toast with the error is shown. If the copy is successful and
* there is a success message, a toast with that message is shown.
* @param {string} content the content to be copied to the clipboard
* @param {string} messageOnSuccess the message to be displayed as a toast when the copy succeeds (optional)
* @param {string} messageOnError the message to be displayed as a toast when the copy fails (optional)
*/
async copyToClipboard ({ dispatch }, { content, messageOnSuccess, messageOnError }) {
if (navigator.clipboard !== undefined && window.isSecureContext) {
try {
await navigator.clipboard.writeText(content)
if (messageOnSuccess !== undefined) {
dispatch('showToast', {
message: messageOnSuccess
})
}
} catch (error) {
console.error(`Failed to copy ${content} to clipboard`, error)
if (messageOnError !== undefined) {
dispatch('showToast', {
message: `${messageOnError}: ${error}`,
time: 5000
})
} else {
dispatch('showToast', {
message: `${i18n.t('Clipboard.Copy failed')}: ${error}`,
time: 5000
})
}
}
} else {
dispatch('showToast', {
message: i18n.t('Clipboard.Cannot access clipboard without a secure connection'),
time: 5000
})
}
},
async downloadMedia({ rootState, dispatch }, { url, title, extension, fallingBackPath }) {
const fileName = `${await dispatch('replaceFilenameForbiddenChars', title)}.${extension}`
const locale = i18n._vm.locale

View File

@ -310,7 +310,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'local' && this.backendFallback) {
@ -342,7 +342,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'local' && this.backendFallback) {
@ -367,7 +367,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
})
@ -422,7 +422,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err.responseJSON.error}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err.responseJSON.error })
}
})
this.isLoading = false
@ -450,7 +450,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
})
@ -477,7 +477,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'local' && this.backendFallback) {
@ -503,7 +503,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
})
@ -529,7 +529,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err.responseJSON.error}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err.responseJSON.error)
this.copyToClipboard({ content: err.responseJSON.error })
}
})
if (this.backendPreference === 'invidious' && this.backendFallback) {
@ -572,7 +572,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err.responseJSON.error}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err.responseJSON.error)
this.copyToClipboard({ content: err.responseJSON.error })
}
})
if (this.backendPreference === 'invidious' && this.backendFallback) {
@ -738,7 +738,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'local' && this.backendFallback) {
@ -763,7 +763,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
})
@ -791,7 +791,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'invidious' && this.backendFallback) {
@ -810,7 +810,8 @@ export default Vue.extend({
'updateProfile',
'invidiousGetChannelInfo',
'invidiousAPICall',
'updateSubscriptionDetails'
'updateSubscriptionDetails',
'copyToClipboard'
])
}
})

View File

@ -207,7 +207,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'local' && this.backendFallback) {
@ -279,7 +279,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'invidious' && this.backendFallback) {
@ -345,7 +345,8 @@ export default Vue.extend({
...mapActions([
'showToast',
'ytSearch',
'invidiousAPICall'
'invidiousAPICall',
'copyToClipboard'
])
}
})

View File

@ -260,7 +260,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
switch (failedAttempts) {
@ -323,7 +323,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
switch (failedAttempts) {
@ -371,7 +371,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err.responseText}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err.responseText })
}
})
switch (failedAttempts) {
@ -422,7 +422,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (err.toString().match(/500/)) {
@ -465,7 +465,8 @@ export default Vue.extend({
'updateShowProgressBar',
'updateProfileSubscriptions',
'updateAllSubscriptionsList',
'calculatePublishedDate'
'calculatePublishedDate',
'copyToClipboard'
]),
...mapMutations([

View File

@ -132,7 +132,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
if (this.backendPreference === 'local' && this.backendFallback) {
@ -191,7 +191,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err.responseText}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err.responseText })
}
})
@ -208,7 +208,8 @@ export default Vue.extend({
...mapActions([
'showToast',
'invidiousAPICall'
'invidiousAPICall',
'copyToClipboard'
])
}
})

View File

@ -593,7 +593,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
console.log(err)
@ -778,7 +778,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err.responseText}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err.responseText)
this.copyToClipboard({ content: err.responseText })
}
})
console.log(err)
@ -949,7 +949,7 @@ export default Vue.extend({
message: `${errorMessage}: ${err}`,
time: 10000,
action: () => {
navigator.clipboard.writeText(err)
this.copyToClipboard({ content: err })
}
})
console.log(err)
@ -1409,7 +1409,8 @@ export default Vue.extend({
'getUserDataPath',
'ytGetVideoInformation',
'invidiousGetVideoInformation',
'updateSubscriptionDetails'
'updateSubscriptionDetails',
'copyToClipboard'
])
}
})

View File

@ -688,6 +688,9 @@ Share:
YouTube URL copied to clipboard: YouTube URL copied to clipboard
YouTube Embed URL copied to clipboard: YouTube Embed URL copied to clipboard
YouTube Channel URL copied to clipboard: YouTube Channel URL copied to clipboard
Clipboard:
Copy failed: Copy to clipboard failed
Cannot access clipboard without a secure connection: Cannot access clipboard without a secure connection
Mini Player: Mini Player
Comments: