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 InputText from 'primevue/inputtext';
import Button from 'primevue/button';
import Dialog from 'primevue/dialog';
import { useToast } from 'primevue/usetoast';
const toast = useToast();
const getPlaylistId = useGetPlaylistId();
const { copy } = useClipboard();
const { isSupported, clipboardWirtePermission, canCopyToClipboard } =
useCanCopyToClipboard();
const { canCopyToClipboard } = useCanCopyToClipboard();
const playlistUrl = ref('');
const idToShow = ref('');
const canShowFallbackDialog = ref(false);
const actionButtonLabel = computed(() =>
canCopyToClipboard.value ? 'Copy ID' : 'Show ID'
@ -23,11 +24,13 @@ const copyOrShowPlaylistId = async () => {
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);
playlistUrl.value = '';
toast.add({
severity: 'success',
summary: 'Success',
@ -40,22 +43,13 @@ const copyOrShowPlaylistId = async () => {
<template>
<NuxtLayout name="centered-content">
<div class="mx-4">
<h1 id="get-playlist-id-headline" class="m-0">
Get playlist's ID from URL
</h1>
<ClientOnly>
<template #fallback>
<ProgressSpinner />
</template>
<p v-if="!canCopyToClipboard">
You could have the button below copy the ID upon clicking, but
<span v-if="!isSupported">
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>
<h1 id="get-playlist-id-headline" class="m-0">
Get playlist's ID from URL
</h1>
<InputText
v-model="playlistUrl"
class="w-full my-3"
@ -67,9 +61,18 @@ const copyOrShowPlaylistId = async () => {
:label="actionButtonLabel"
@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>
</p>
<template #footer>
<Button label="OK" @click="canShowFallbackDialog = false" />
</template>
</Dialog>
</ClientOnly>
</div>
</NuxtLayout>

View File

@ -3,6 +3,7 @@ import { decode as decodeHtmlEntities } from 'html-entities';
import formatDuration from 'format-duration';
import Button from 'primevue/button';
import Dialog from 'primevue/dialog';
import { useToast } from 'primevue/usetoast';
import { Snapshot } from '~~/models/snapshot';
@ -11,8 +12,8 @@ const route = useRoute();
const toast = useToast();
const { copy } = useClipboard();
const { isSupported, clipboardWirtePermission, canCopyToClipboard } =
useCanCopyToClipboard();
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { isSupported, canCopyToClipboard } = useCanCopyToClipboard();
const playlistId = route.params.playlistId 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 humanizeNumber = (num: number) => numberFormatter.format(num);
const copyTrackUrls = async () => {
const trackUrls = snapshot.value.tracks.map(({ url }) => url).join('\n');
const trackUrlsToCopy = ref('');
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({
severity: 'success',
@ -94,19 +97,10 @@ const copyTrackUrls = async () => {
</li>
</ul>
<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
v-tooltip.hover="copyTrackUrlsTooltip"
class="p-button-text"
label="Copy track URLs"
:label="copyTrackUrlsButtonLabel"
icon="pi pi-clone"
:disabled="!canCopyToClipboard"
@click="copyTrackUrls"
/>
<a
@ -123,6 +117,25 @@ const copyTrackUrls = async () => {
</div>
</div>
<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
:loading="pending"
:tracks="snapshot.tracks"