If clipboard is unavailable, show actions dialogs

This commit is contained in:
Maciej Pędzich 2022-09-05 13:39:48 +02:00
parent 92d499c005
commit 12ac4a661b
2 changed files with 58 additions and 42 deletions

View File

@ -2,17 +2,18 @@
import ProgressSpinner from 'primevue/progressspinner'; import ProgressSpinner from 'primevue/progressspinner';
import InputText from 'primevue/inputtext'; import InputText from 'primevue/inputtext';
import Button from 'primevue/button'; import Button from 'primevue/button';
import Dialog from 'primevue/dialog';
import { useToast } from 'primevue/usetoast'; import { useToast } from 'primevue/usetoast';
const toast = useToast(); const toast = useToast();
const getPlaylistId = useGetPlaylistId(); const getPlaylistId = useGetPlaylistId();
const { copy } = useClipboard(); const { copy } = useClipboard();
const { isSupported, clipboardWirtePermission, canCopyToClipboard } = const { canCopyToClipboard } = useCanCopyToClipboard();
useCanCopyToClipboard();
const playlistUrl = ref(''); const playlistUrl = ref('');
const idToShow = ref(''); const idToShow = ref('');
const canShowFallbackDialog = ref(false);
const actionButtonLabel = computed(() => const actionButtonLabel = computed(() =>
canCopyToClipboard.value ? 'Copy ID' : 'Show ID' canCopyToClipboard.value ? 'Copy ID' : 'Show ID'
@ -23,11 +24,13 @@ const copyOrShowPlaylistId = async () => {
const playlistId = getPlaylistId(playlistUrl.value); const playlistId = getPlaylistId(playlistUrl.value);
if (!canCopyToClipboard.value) return (idToShow.value = playlistId); if (!canCopyToClipboard.value) {
idToShow.value = playlistId;
canShowFallbackDialog.value = true;
return;
}
await copy(playlistId); await copy(playlistId);
playlistUrl.value = '';
toast.add({ toast.add({
severity: 'success', severity: 'success',
summary: 'Success', summary: 'Success',
@ -40,22 +43,13 @@ const copyOrShowPlaylistId = async () => {
<template> <template>
<NuxtLayout name="centered-content"> <NuxtLayout name="centered-content">
<div class="mx-4"> <div class="mx-4">
<h1 id="get-playlist-id-headline" class="m-0">
Get playlist's ID from URL
</h1>
<ClientOnly> <ClientOnly>
<template #fallback> <template #fallback>
<ProgressSpinner /> <ProgressSpinner />
</template> </template>
<p v-if="!canCopyToClipboard"> <h1 id="get-playlist-id-headline" class="m-0">
You could have the button below copy the ID upon clicking, but Get playlist's ID from URL
<span v-if="!isSupported"> </h1>
your browser doesn't support functionality required to do so.
</span>
<span v-else-if="clipboardWirtePermission !== 'granted'">
you need to grant this website permission to copy text to clipboard.
</span>
</p>
<InputText <InputText
v-model="playlistUrl" v-model="playlistUrl"
class="w-full my-3" class="w-full my-3"
@ -67,9 +61,18 @@ const copyOrShowPlaylistId = async () => {
:label="actionButtonLabel" :label="actionButtonLabel"
@click="copyOrShowPlaylistId" @click="copyOrShowPlaylistId"
/> />
<p v-if="!canCopyToClipboard && idToShow"> <Dialog
header="Success"
:visible="canShowFallbackDialog"
:draggable="false"
:closable="false"
modal
>
This playlist's ID is: <strong>{{ idToShow }}</strong> This playlist's ID is: <strong>{{ idToShow }}</strong>
</p> <template #footer>
<Button label="OK" @click="canShowFallbackDialog = false" />
</template>
</Dialog>
</ClientOnly> </ClientOnly>
</div> </div>
</NuxtLayout> </NuxtLayout>

View File

@ -3,6 +3,7 @@ import { decode as decodeHtmlEntities } from 'html-entities';
import formatDuration from 'format-duration'; import formatDuration from 'format-duration';
import Button from 'primevue/button'; import Button from 'primevue/button';
import Dialog from 'primevue/dialog';
import { useToast } from 'primevue/usetoast'; import { useToast } from 'primevue/usetoast';
import { Snapshot } from '~~/models/snapshot'; import { Snapshot } from '~~/models/snapshot';
@ -11,8 +12,8 @@ const route = useRoute();
const toast = useToast(); const toast = useToast();
const { copy } = useClipboard(); const { copy } = useClipboard();
const { isSupported, clipboardWirtePermission, canCopyToClipboard } = // eslint-disable-next-line @typescript-eslint/no-unused-vars
useCanCopyToClipboard(); const { isSupported, canCopyToClipboard } = useCanCopyToClipboard();
const playlistId = route.params.playlistId as string; const playlistId = route.params.playlistId as string;
const commitSha = route.params.commitSha as string; const commitSha = route.params.commitSha as string;
@ -47,21 +48,23 @@ const totalTrackDuration = computed(() =>
) )
); );
const copyTrackUrlsTooltip = computed(() =>
!isSupported.value
? "Your browser doesn't support this feature"
: clipboardWirtePermission.value !== 'granted'
? 'You need to grant this website permission to copy to clipboard'
: null
);
const numberFormatter = new Intl.NumberFormat('en-US'); const numberFormatter = new Intl.NumberFormat('en-US');
const humanizeNumber = (num: number) => numberFormatter.format(num); const humanizeNumber = (num: number) => numberFormatter.format(num);
const copyTrackUrls = async () => { const trackUrlsToCopy = ref('');
const trackUrls = snapshot.value.tracks.map(({ url }) => url).join('\n'); const canShowFallbackDialog = ref(false);
await copy(trackUrls); const copyTrackUrlsButtonLabel = computed(() =>
canCopyToClipboard.value ? 'Copy track URLs' : 'Show track URLs to copy'
);
const copyTrackUrls = async () => {
trackUrlsToCopy.value = snapshot.value.tracks
.map(({ url }) => url)
.join('\n');
if (!canCopyToClipboard.value) return (canShowFallbackDialog.value = true);
await copy(trackUrlsToCopy.value);
toast.add({ toast.add({
severity: 'success', severity: 'success',
@ -94,19 +97,10 @@ const copyTrackUrls = async () => {
</li> </li>
</ul> </ul>
<div class="my-2 flex justify-content-center"> <div class="my-2 flex justify-content-center">
<span
v-if="!canCopyToClipboard"
v-tooltip.top="copyTrackUrlsTooltip"
class="flex align-items-center text-blue-300"
>
<i class="pi pi-info-circle"></i>
</span>
<Button <Button
v-tooltip.hover="copyTrackUrlsTooltip"
class="p-button-text" class="p-button-text"
label="Copy track URLs" :label="copyTrackUrlsButtonLabel"
icon="pi pi-clone" icon="pi pi-clone"
:disabled="!canCopyToClipboard"
@click="copyTrackUrls" @click="copyTrackUrls"
/> />
<a <a
@ -123,6 +117,25 @@ const copyTrackUrls = async () => {
</div> </div>
</div> </div>
<ClientOnly> <ClientOnly>
<Dialog
:visible="canShowFallbackDialog"
:draggable="false"
:closable="false"
:show-header="false"
modal
>
<p class="font-bold text-xl text-center">
Copy the track URLs below:
</p>
<pre class="w-4 h-10rem">{{ trackUrlsToCopy }}</pre>
<template #footer>
<Button
class="mt-3"
label="OK"
@click="canShowFallbackDialog = false"
/>
</template>
</Dialog>
<SnapshotTrackEntries <SnapshotTrackEntries
:loading="pending" :loading="pending"
:tracks="snapshot.tracks" :tracks="snapshot.tracks"