Update copy to clipboard buttons to be standardized

This commit is contained in:
advplyr 2025-01-22 17:56:46 -06:00
parent c3c846f82d
commit 598a93d224
8 changed files with 33 additions and 53 deletions

View File

@ -90,8 +90,8 @@
<div class="relative"> <div class="relative">
<ui-textarea-with-label :value="prettyFfprobeData" readonly :rows="30" class="text-xs" /> <ui-textarea-with-label :value="prettyFfprobeData" readonly :rows="30" class="text-xs" />
<button class="absolute top-4 right-4" :class="copiedToClipboard ? 'text-success' : 'text-white/50 hover:text-white/80'" @click.stop="copyFfprobeData"> <button class="absolute top-4 right-4" :class="hasCopied ? 'text-success' : 'text-gray-400 hover:text-white'" @click.stop="copyToClipboard">
<span class="material-symbols">{{ copiedToClipboard ? 'check' : 'content_copy' }}</span> <span class="material-symbols">{{ hasCopied ? 'done' : 'content_copy' }}</span>
</button> </button>
</div> </div>
</div> </div>
@ -113,14 +113,13 @@ export default {
return { return {
probingFile: false, probingFile: false,
ffprobeData: null, ffprobeData: null,
copiedToClipboard: false hasCopied: null
} }
}, },
watch: { watch: {
show(newVal) { show(newVal) {
if (newVal) { if (newVal) {
this.ffprobeData = null this.ffprobeData = null
this.copiedToClipboard = false
this.probingFile = false this.probingFile = false
} }
} }
@ -165,8 +164,13 @@ export default {
this.probingFile = false this.probingFile = false
}) })
}, },
async copyFfprobeData() { copyToClipboard() {
this.copiedToClipboard = await this.$copyToClipboard(this.prettyFfprobeData) clearTimeout(this.hasCopied)
this.$copyToClipboard(this.prettyFfprobeData).then((success) => {
this.hasCopied = setTimeout(() => {
this.hasCopied = null
}, 2000)
})
} }
}, },
mounted() {} mounted() {}

View File

@ -16,7 +16,7 @@
<template v-if="currentShare"> <template v-if="currentShare">
<div class="w-full py-2"> <div class="w-full py-2">
<label class="px-1 text-sm font-semibold block">{{ $strings.LabelShareURL }}</label> <label class="px-1 text-sm font-semibold block">{{ $strings.LabelShareURL }}</label>
<ui-text-input v-model="currentShareUrl" show-copy readonly class="text-base h-10" /> <ui-text-input v-model="currentShareUrl" show-copy readonly />
</div> </div>
<div class="w-full py-2 px-1"> <div class="w-full py-2 px-1">
<p v-if="currentShare.isDownloadable" class="text-sm mb-2">{{ $strings.LabelDownloadable }}</p> <p v-if="currentShare.isDownloadable" class="text-sm mb-2">{{ $strings.LabelDownloadable }}</p>

View File

@ -10,9 +10,7 @@
<p class="text-lg font-semibold mb-4">{{ $strings.HeaderRSSFeedIsOpen }}</p> <p class="text-lg font-semibold mb-4">{{ $strings.HeaderRSSFeedIsOpen }}</p>
<div class="w-full relative"> <div class="w-full relative">
<ui-text-input :value="feedUrl" readonly /> <ui-text-input :value="feedUrl" readonly show-copy />
<span class="material-symbols absolute right-2 bottom-2 p-0.5 text-base transition-transform duration-100 transform hover:scale-125 cursor-pointer" :class="copiedToClipboard ? 'text-success' : 'text-gray-300 hover:text-white'" @click="copyToClipboard(feedUrl)">{{ copiedToClipboard ? 'check' : 'content_copy' }}</span>
</div> </div>
<div v-if="currentFeed.meta" class="mt-5"> <div v-if="currentFeed.meta" class="mt-5">
@ -68,8 +66,7 @@ export default {
preventIndexing: true, preventIndexing: true,
ownerName: '', ownerName: '',
ownerEmail: '' ownerEmail: ''
}, }
copiedToClipboard: false
} }
}, },
watch: { watch: {
@ -161,12 +158,6 @@ export default {
this.processing = false this.processing = false
}) })
}, },
async copyToClipboard(str) {
this.copiedToClipboard = await this.$copyToClipboard(str)
setTimeout(() => {
this.copiedToClipboard = false
}, 2000)
},
closeFeed() { closeFeed() {
this.processing = true this.processing = true
this.$axios this.$axios

View File

@ -5,8 +5,7 @@
<p class="text-lg font-semibold mb-4">{{ $strings.HeaderRSSFeedGeneral }}</p> <p class="text-lg font-semibold mb-4">{{ $strings.HeaderRSSFeedGeneral }}</p>
<div class="w-full relative"> <div class="w-full relative">
<ui-text-input :value="feedUrl" readonly /> <ui-text-input :value="feedUrl" readonly show-copy />
<span class="material-symbols absolute right-2 bottom-2 p-0.5 text-base transition-transform duration-100 transform hover:scale-125 cursor-pointer" :class="copiedToClipboard ? 'text-success' : 'text-gray-300 hover:text-white'" @click="copyToClipboard(feedUrl)">{{ copiedToClipboard ? 'check' : 'content_copy' }}</span>
</div> </div>
<div v-if="feed.meta" class="mt-5"> <div v-if="feed.meta" class="mt-5">
@ -56,8 +55,7 @@ export default {
}, },
data() { data() {
return { return {
processing: false, processing: false
copiedToClipboard: false
} }
}, },
computed: { computed: {
@ -75,16 +73,7 @@ export default {
feedUrl() { feedUrl() {
return this.feed ? `${window.origin}${this.$config.routerBasePath}${this.feed.feedUrl}` : '' return this.feed ? `${window.origin}${this.$config.routerBasePath}${this.feed.feedUrl}` : ''
} }
},
methods: {
async copyToClipboard(str) {
this.copiedToClipboard = await this.$copyToClipboard(str)
setTimeout(() => {
this.copiedToClipboard = false
}, 2000)
} }
},
mounted() {}
} }
</script> </script>

View File

@ -7,8 +7,8 @@
<div v-if="type === 'password' && isHovering" class="absolute top-0 right-0 h-full px-4 flex items-center justify-center"> <div v-if="type === 'password' && isHovering" class="absolute top-0 right-0 h-full px-4 flex items-center justify-center">
<span class="material-symbols text-gray-400 cursor-pointer text-lg" @click.stop.prevent="showPassword = !showPassword">{{ !showPassword ? 'visibility' : 'visibility_off' }}</span> <span class="material-symbols text-gray-400 cursor-pointer text-lg" @click.stop.prevent="showPassword = !showPassword">{{ !showPassword ? 'visibility' : 'visibility_off' }}</span>
</div> </div>
<div v-else-if="showCopy" class="absolute top-0 right-0 h-full px-4 flex items-center justify-center"> <div v-else-if="showCopy" class="absolute top-0 right-0 h-full px-2 flex items-center justify-center">
<span class="material-symbols text-gray-400 cursor-pointer text-lg" @click.stop.prevent="copyToClipboard">{{ !hasCopied ? 'content_copy' : 'done' }}</span> <span class="material-symbols cursor-pointer text-lg" :class="hasCopied ? 'text-success' : 'text-gray-400 hover:text-white'" @click.stop.prevent="copyToClipboard">{{ !hasCopied ? 'content_copy' : 'done' }}</span>
</div> </div>
</div> </div>
</template> </template>
@ -47,7 +47,7 @@ export default {
showPassword: false, showPassword: false,
isHovering: false, isHovering: false,
isFocused: false, isFocused: false,
hasCopied: false, hasCopied: null,
isInvalidDate: false isInvalidDate: false
} }
}, },
@ -62,7 +62,12 @@ export default {
}, },
classList() { classList() {
var _list = [] var _list = []
if (this.showCopy) {
_list.push('pl-3', 'pr-8')
} else {
_list.push(`px-${this.paddingX}`) _list.push(`px-${this.paddingX}`)
}
_list.push(`py-${this.paddingY}`) _list.push(`py-${this.paddingY}`)
if (this.noSpinner) _list.push('no-spinner') if (this.noSpinner) _list.push('no-spinner')
if (this.textCenter) _list.push('text-center') if (this.textCenter) _list.push('text-center')
@ -80,11 +85,10 @@ export default {
}, },
methods: { methods: {
copyToClipboard() { copyToClipboard() {
if (this.hasCopied) return clearTimeout(this.hasCopied)
this.$copyToClipboard(this.inputValue).then((success) => { this.$copyToClipboard(this.inputValue).then((success) => {
this.hasCopied = success this.hasCopied = setTimeout(() => {
setTimeout(() => { this.hasCopied = null
this.hasCopied = false
}, 2000) }, 2000)
}) })
}, },

View File

@ -6,7 +6,7 @@
<em v-if="note" class="font-normal text-xs pl-2">{{ note }}</em> <em v-if="note" class="font-normal text-xs pl-2">{{ note }}</em>
</label> </label>
</slot> </slot>
<ui-text-input :placeholder="placeholder || label" :inputId="identifier" ref="input" v-model="inputValue" :disabled="disabled" :readonly="readonly" :type="type" class="w-full" :class="inputClass" @blur="inputBlurred" /> <ui-text-input :placeholder="placeholder || label" :inputId="identifier" ref="input" v-model="inputValue" :disabled="disabled" :readonly="readonly" :type="type" :show-copy="showCopy" class="w-full" :class="inputClass" @blur="inputBlurred" />
</div> </div>
</template> </template>
@ -23,7 +23,8 @@ export default {
}, },
readonly: Boolean, readonly: Boolean,
disabled: Boolean, disabled: Boolean,
inputClass: String inputClass: String,
showCopy: Boolean
}, },
data() { data() {
return {} return {}

View File

@ -14,11 +14,7 @@
<h1 class="text-xl pl-2">{{ username }}</h1> <h1 class="text-xl pl-2">{{ username }}</h1>
</div> </div>
<div v-if="userToken" class="flex text-xs mt-4"> <div v-if="userToken" class="flex text-xs mt-4">
<ui-text-input-with-label :label="$strings.LabelApiToken" :value="userToken" readonly /> <ui-text-input-with-label :label="$strings.LabelApiToken" :value="userToken" readonly show-copy />
<div class="px-1 mt-8 cursor-pointer" @click="copyToClipboard(userToken)">
<span class="material-symbols pl-2 text-base">content_copy</span>
</div>
</div> </div>
<div class="w-full h-px bg-white bg-opacity-10 my-2" /> <div class="w-full h-px bg-white bg-opacity-10 my-2" />
<div class="py-2"> <div class="py-2">
@ -140,9 +136,6 @@ export default {
} }
}, },
methods: { methods: {
copyToClipboard(str) {
this.$copyToClipboard(str, this)
},
async init() { async init() {
this.listeningSessions = await this.$axios this.listeningSessions = await this.$axios
.$get(`/api/users/${this.user.id}/listening-sessions?page=0&itemsPerPage=10`) .$get(`/api/users/${this.user.id}/listening-sessions?page=0&itemsPerPage=10`)

View File

@ -128,12 +128,11 @@ Vue.prototype.$sanitizeSlug = (str) => {
return str return str
} }
Vue.prototype.$copyToClipboard = (str, ctx) => { Vue.prototype.$copyToClipboard = (str) => {
return new Promise((resolve) => { return new Promise((resolve) => {
if (navigator.clipboard) { if (navigator.clipboard) {
navigator.clipboard.writeText(str).then( navigator.clipboard.writeText(str).then(
() => { () => {
if (ctx) ctx.$toast.success('Copied to clipboard')
resolve(true) resolve(true)
}, },
(err) => { (err) => {
@ -152,7 +151,6 @@ Vue.prototype.$copyToClipboard = (str, ctx) => {
document.execCommand('copy') document.execCommand('copy')
document.body.removeChild(el) document.body.removeChild(el)
if (ctx) ctx.$toast.success('Copied to clipboard')
resolve(true) resolve(true)
} }
}) })