Implement copying track URLs and JSON export

This commit is contained in:
Maciej Pędzich 2022-09-03 16:30:31 +02:00
parent 8e07da612c
commit c6a8ca32e4

View File

@ -2,25 +2,43 @@
import { decode as decodeHtmlEntities } from 'html-entities'; import { decode as decodeHtmlEntities } from 'html-entities';
import formatDuration from 'format-duration'; import formatDuration from 'format-duration';
import Button from 'primevue/button';
import { useToast } from 'primevue/usetoast';
import { Snapshot } from '~~/models/snapshot'; import { Snapshot } from '~~/models/snapshot';
const route = useRoute(); const route = useRoute();
const toast = useToast();
const { copy } = useClipboard();
const { 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;
const snapshotDataUrl = `https://raw.githubusercontent.com/mackorone/spotify-playlist-archive/${commitSha}/playlists/pretty/${playlistId}.json`;
const { const {
pending, pending,
error, error,
data: snapshot data: snapshot
} = useFetch<Snapshot>( } = useFetch<Snapshot>(snapshotDataUrl, {
() => key: `snapshot-${commitSha}`,
`https://raw.githubusercontent.com/mackorone/spotify-playlist-archive/${commitSha}/playlists/pretty/${playlistId}.json`, parseResponse: JSON.parse
{ });
key: `snapshot-${commitSha}`,
parseResponse: JSON.parse const snapshotJsonFileName = computed(
} () => `${snapshot.value?.unique_name}.json`
); );
const snapshotJsonDownloadUrl = computed(() => {
if (!snapshot.value) return;
const blob = new Blob([JSON.stringify(snapshot.value, null, 2)]);
const url = URL.createObjectURL(blob);
return url;
});
const totalTrackDuration = computed(() => const totalTrackDuration = computed(() =>
(snapshot.value?.tracks || []).reduce( (snapshot.value?.tracks || []).reduce(
(total, track) => (total += track.duration_ms), (total, track) => (total += track.duration_ms),
@ -29,8 +47,20 @@ const totalTrackDuration = computed(() =>
); );
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 trackUrls = snapshot.value.tracks.map(({ url }) => url).join('\n');
await copy(trackUrls);
toast.add({
severity: 'success',
summary: 'Success',
detail: 'URLs have been copied to clipboard',
life: 5000
});
};
</script> </script>
<template> <template>
@ -54,6 +84,26 @@ const humanizeNumber = (num: number) => numberFormatter.format(num);
</span> </span>
</li> </li>
</ul> </ul>
<div class="my-2 flex justify-content-center">
<Button
v-if="canCopyToClipboard"
class="p-button-text"
label="Copy track URLs"
icon="pi pi-clone"
@click="copyTrackUrls"
/>
<a
id="export-to-json"
class="p-component p-button p-button-text"
:href="snapshotJsonDownloadUrl"
:download="snapshotJsonFileName"
>
<span
class="pi pi-download p-button-icon p-button-icon-left"
></span>
<span class="p-button-label">Export to JSON</span>
</a>
</div>
</div> </div>
<ClientOnly> <ClientOnly>
<SnapshotTrackEntries <SnapshotTrackEntries
@ -67,6 +117,12 @@ const humanizeNumber = (num: number) => numberFormatter.format(num);
</template> </template>
<style scoped> <style scoped>
#export-to-json:hover {
background-color: rgba(129, 199, 132, 0.04);
border-color: transparent;
color: #81c784;
}
#snapshot-meta > li:first-of-type { #snapshot-meta > li:first-of-type {
list-style: disc; list-style: disc;
} }