mirror of
https://github.com/maciejpedzich/spotifyplaylistarchive.com.git
synced 2024-09-19 18:16:19 +02:00
If clipboard is unavailable, show actions dialogs
This commit is contained in:
parent
92d499c005
commit
12ac4a661b
@ -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>
|
||||||
|
@ -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"
|
||||||
|
Loading…
Reference in New Issue
Block a user