mirror of
https://github.com/FranP-code/spooky-spotify-showcase.git
synced 2025-10-13 00:02:36 +00:00
Add spooky image generation and saving to album showcase
This commit is contained in:
@@ -1,4 +1,8 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
import { TrackByAlbum } from "./spotify-data";
|
import { TrackByAlbum } from "./spotify-data";
|
||||||
|
import { api } from "@/trpc/react";
|
||||||
|
|
||||||
export default function AlbumShowcase({
|
export default function AlbumShowcase({
|
||||||
album,
|
album,
|
||||||
@@ -9,12 +13,79 @@ export default function AlbumShowcase({
|
|||||||
? album.images[0].url
|
? album.images[0].url
|
||||||
: "https://via.placeholder.com/150";
|
: "https://via.placeholder.com/150";
|
||||||
|
|
||||||
|
const [spookyImageLoaded, setSpookyImageLoaded] = useState(false);
|
||||||
|
|
||||||
|
const entry = api.entry.get.useQuery({
|
||||||
|
type: "album",
|
||||||
|
name: album.name,
|
||||||
|
image: imageSource,
|
||||||
|
});
|
||||||
|
|
||||||
|
const generateSpookyImage = api.entry.generate.useMutation();
|
||||||
|
const saveImage = api.entry.save.useMutation();
|
||||||
|
|
||||||
|
const handleGenerateSpookyImage = async () => {
|
||||||
|
if (!entry.data && !entry.isLoading) {
|
||||||
|
generateSpookyImage.mutate({
|
||||||
|
entry: {
|
||||||
|
type: "album",
|
||||||
|
name: album.name,
|
||||||
|
image: imageSource,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSaveImage = async () => {
|
||||||
|
if (!entry.data && !entry.isLoading) {
|
||||||
|
saveImage.mutate({
|
||||||
|
entry: {
|
||||||
|
type: "album",
|
||||||
|
image: imageSource,
|
||||||
|
name: album.name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
handleGenerateSpookyImage();
|
||||||
|
}, [entry.data]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (spookyImageLoaded) {
|
||||||
|
handleSaveImage();
|
||||||
|
}
|
||||||
|
}, [spookyImageLoaded]);
|
||||||
|
|
||||||
|
//TODO ERROR HANDLING
|
||||||
|
|
||||||
|
const spookyImageMatch = (
|
||||||
|
(entry.data?.value || generateSpookyImage.data) as null | string
|
||||||
|
)?.match(/https:\/\/res.cloudinary.com\/[^"]+/);
|
||||||
|
|
||||||
|
const spookyImageSource = spookyImageMatch ? spookyImageMatch[0] : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={album.id}
|
key={album.id}
|
||||||
className="flex w-full flex-wrap gap-3 rounded-xl bg-white bg-opacity-10 p-5 backdrop-blur-lg backdrop-filter"
|
className="flex w-full flex-wrap gap-3 rounded-xl bg-white bg-opacity-10 p-5 backdrop-blur-lg backdrop-filter"
|
||||||
>
|
>
|
||||||
<img className="h-36 w-36 rounded" src={imageSource} alt={album.name} />
|
<div>
|
||||||
|
<img className="h-36 w-36 rounded" src={imageSource} alt={album.name} />
|
||||||
|
{!!spookyImageSource && (
|
||||||
|
<img
|
||||||
|
className="h-36 w-36 rounded"
|
||||||
|
src={spookyImageSource}
|
||||||
|
alt={album.name}
|
||||||
|
onLoad={() => {
|
||||||
|
if (!spookyImageLoaded && generateSpookyImage.data) {
|
||||||
|
setSpookyImageLoaded(true);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<section className="flex h-36 flex-grow flex-col">
|
<section className="flex h-36 flex-grow flex-col">
|
||||||
<h4 className="mb-2 text-lg font-semibold leading-none">
|
<h4 className="mb-2 text-lg font-semibold leading-none">
|
||||||
{album.name}
|
{album.name}
|
||||||
@@ -23,6 +94,7 @@ export default function AlbumShowcase({
|
|||||||
{tracks.map((track) => (
|
{tracks.map((track) => (
|
||||||
<li key={track.id}>{track.name}</li>
|
<li key={track.id}>{track.name}</li>
|
||||||
))}
|
))}
|
||||||
|
{JSON.stringify(generateSpookyImage.data)}
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import SpotifyWebApi from "spotify-web-api-node";
|
import SpotifyWebApi from "spotify-web-api-node";
|
||||||
import AlbumShowcase from "./album-showcase";
|
import AlbumShowcase from "./album-showcase";
|
||||||
import ArtistShowcase from "./artist-showcase";
|
import ArtistShowcase from "./artist-showcase";
|
||||||
|
import { TRPCReactProvider } from "@/trpc/react";
|
||||||
|
|
||||||
const TRACKS_LIMIT = 20;
|
const TRACKS_LIMIT = 20;
|
||||||
const ARTISTS_LIMIT = 21;
|
const ARTISTS_LIMIT = 21;
|
||||||
@@ -109,10 +110,6 @@ export default async function SpotifyData({
|
|||||||
// // tracks: Track[];
|
// // tracks: Track[];
|
||||||
// // tracksByAlbum: { [key: string]: Album };
|
// // tracksByAlbum: { [key: string]: Album };
|
||||||
// // };
|
// // };
|
||||||
console.log("Albums:", albums);
|
|
||||||
console.log("Artists:", artists);
|
|
||||||
console.log("Tracks:", tracks);
|
|
||||||
console.log("Tracks by album:", tracksByAlbum);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -143,12 +140,13 @@ export default async function SpotifyData({
|
|||||||
})}
|
})}
|
||||||
</div> */}
|
</div> */}
|
||||||
|
|
||||||
<h3>Tracks by album</h3>
|
{/* TODO CHECK IF NEEDED */}
|
||||||
{Object.values(tracksByAlbum)
|
<TRPCReactProvider>
|
||||||
.sort((a, b) => b.position - a.position)
|
<h3>Tracks by album</h3>
|
||||||
.map((album) => (
|
{Object.values(tracksByAlbum)
|
||||||
<AlbumShowcase {...album} />
|
.sort((a, b) => b.position - a.position)
|
||||||
))}
|
.map((album, index) => !index && <AlbumShowcase {...album} />)}
|
||||||
|
</TRPCReactProvider>
|
||||||
|
|
||||||
{/* <h3>Albums images</h3>
|
{/* <h3>Albums images</h3>
|
||||||
<div
|
<div
|
||||||
|
|||||||
Reference in New Issue
Block a user