mirror of
https://github.com/maciejpedzich/spotifyplaylistarchive.com.git
synced 2024-09-19 18:16:19 +02:00
Implement copying track URLs and JSON export
This commit is contained in:
parent
8e07da612c
commit
c6a8ca32e4
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user