Updated prompt and added queue system

This commit is contained in:
2024-10-12 01:02:23 -03:00
parent a11ed74017
commit 6fdb87c32a
6 changed files with 177 additions and 65 deletions

View File

@@ -6,7 +6,9 @@ import { TrackByAlbum } from "./spotify-data";
import { api } from "@/trpc/react"; import { api } from "@/trpc/react";
import { quantum } from "ldrs"; import { quantum } from "ldrs";
import { ring2 } from "ldrs"; import { ring2 } from "ldrs";
import { pulsar } from "ldrs";
pulsar.register();
ring2.register(); ring2.register();
quantum.register(); quantum.register();
@@ -15,7 +17,15 @@ export default function AlbumShowcase({
album, album,
position, position,
tracks, tracks,
}: TrackByAlbum & { spookify: boolean }) { place,
lastSpookyImageLoaded,
setLastSpookyImageLoaded,
}: TrackByAlbum & {
spookify: boolean;
place: number;
lastSpookyImageLoaded: number;
setLastSpookyImageLoaded: any;
}) {
const imageSource = album.images[0] const imageSource = album.images[0]
? album.images[0].url ? album.images[0].url
: "https://via.placeholder.com/150"; : "https://via.placeholder.com/150";
@@ -77,7 +87,15 @@ export default function AlbumShowcase({
)?.match(/https:\/\/res.cloudinary.com\/[^"]+/); )?.match(/https:\/\/res.cloudinary.com\/[^"]+/);
const spookyImageSource = spookyImageMatch ? spookyImageMatch[0] : null; const spookyImageSource = spookyImageMatch ? spookyImageMatch[0] : null;
console.log(spookyImageSource);
const onImageLoad = () => {
if (!spookyImageLoaded) {
setSpookyImageLoaded(true);
setLastSpookyImageLoaded((state: number) =>
state > place ? state : place,
);
}
};
return ( return (
<div <div
@@ -97,40 +115,65 @@ export default function AlbumShowcase({
src={imageSource} src={imageSource}
alt={album.name} alt={album.name}
/> />
{!!spookyImageSource && ( {spookyImageSource &&
<img (generateSpookyImage.data
className="h-36 w-36 cursor-pointer rounded" ? lastSpookyImageLoaded >= place ||
style={{ lastSpookyImageLoaded + 1 === place
display: : true) && (
showSpookyImage && spookyImageLoaded ? "block" : "none", <img
}} className="h-36 w-36 cursor-pointer rounded"
src={spookyImageSource} style={{
alt={album.name} display:
onLoad={() => { showSpookyImage && spookyImageLoaded ? "block" : "none",
if (!spookyImageLoaded) { }}
setSpookyImageLoaded(true); src={spookyImageSource}
} alt={album.name}
}} onLoad={onImageLoad}
/> onError={() => {
)} onImageLoad();
}}
/>
)}
{showSpookyImage && !spookyImageLoaded && ( {showSpookyImage && !spookyImageLoaded && (
<div className="flex h-36 w-36 items-center justify-center rounded bg-slate-300 bg-opacity-10"> <div className="flex h-36 w-36 items-center justify-center rounded bg-slate-300 bg-opacity-10">
<div> <div>
{generateSpookyImage.data ? ( {(() => {
<> if (generateSpookyImage.data) {
<l-quantum if (lastSpookyImageLoaded < place - 1) {
size="100" return (
speed="1.75" <>
color="white" <l-pulsar
></l-quantum> size="100"
<p className="text-center">Generating...</p> speed="1.75"
</> color="white"
) : ( ></l-pulsar>{" "}
<> <p className="text-center">On queue...</p>
<l-ring-2 size="100" speed="1.75" color="white"></l-ring-2> </>
<p className="text-center">Getting image...</p> );
</> }
)} return (
<>
<l-quantum
size="100"
speed="1.75"
color="white"
></l-quantum>
<p className="text-center">Generating...</p>
</>
);
} else {
return (
<>
<l-ring-2
size="100"
speed="1.75"
color="white"
></l-ring-2>
<p className="text-center">Getting image...</p>
</>
);
}
})()}
</div> </div>
</div> </div>
)} )}
@@ -144,7 +187,6 @@ 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>

View File

@@ -14,11 +14,17 @@ export default function ArtistShowcase({
images, images,
name, name,
id, id,
place,
lastSpookyImageLoaded,
setLastSpookyImageLoaded,
}: { }: {
spookify: boolean; spookify: boolean;
images: { url: string }[]; images: { url: string }[];
name: string; name: string;
id: string; id: string;
place: number;
lastSpookyImageLoaded: number;
setLastSpookyImageLoaded: any;
}) { }) {
const [showSpookyImage, setShowSpookyImage] = useState(spookify); const [showSpookyImage, setShowSpookyImage] = useState(spookify);
const [spookyImageLoaded, setSpookyImageLoaded] = useState(false); const [spookyImageLoaded, setSpookyImageLoaded] = useState(false);
@@ -79,6 +85,15 @@ export default function ArtistShowcase({
)?.match(/https:\/\/res.cloudinary.com\/[^"]+/); )?.match(/https:\/\/res.cloudinary.com\/[^"]+/);
const spookyImageSource = spookyImageMatch ? spookyImageMatch[0] : null; const spookyImageSource = spookyImageMatch ? spookyImageMatch[0] : null;
const onImageLoad = () => {
if (!spookyImageLoaded) {
setSpookyImageLoaded(true);
setLastSpookyImageLoaded((state: number) =>
state > place ? state : place,
);
}
};
return ( return (
<Tilt tiltMaxAngleX={10} tiltMaxAngleY={10} transitionSpeed={200}> <Tilt tiltMaxAngleX={10} tiltMaxAngleY={10} transitionSpeed={200}>
<div <div
@@ -93,25 +108,29 @@ export default function ArtistShowcase({
src={imageSource} src={imageSource}
alt={name} alt={name}
/> />
{!!spookyImageSource && ( {spookyImageSource &&
<img (generateSpookyImage.data
style={{ ? lastSpookyImageLoaded >= place ||
display: showSpookyImage && spookyImageLoaded ? "block" : "none", lastSpookyImageLoaded + 1 === place
}} : true) && (
className="h-56 w-56 object-fill" <img
onLoad={() => { style={{
if (!spookyImageLoaded) { display:
setSpookyImageLoaded(true); showSpookyImage && spookyImageLoaded ? "block" : "none",
} }}
}} className="h-56 w-56 object-fill"
src={spookyImageSource} onLoad={onImageLoad}
alt={name} onError={() => {
/> onImageLoad();
)} }}
src={spookyImageSource}
alt={name}
/>
)}
{showSpookyImage && !spookyImageLoaded && ( {showSpookyImage && !spookyImageLoaded && (
<div className="flex h-56 w-56 items-center justify-center"> <div className="flex h-56 w-56 items-center justify-center">
<div> <div>
{generateSpookyImage.data ? ( {/* {generateSpookyImage.data ? (
<> <>
<l-quantum size="165" speed="1.75" color="white"></l-quantum> <l-quantum size="165" speed="1.75" color="white"></l-quantum>
<p className="text-center">Generating...</p> <p className="text-center">Generating...</p>
@@ -128,7 +147,39 @@ export default function ArtistShowcase({
></l-ring-2> ></l-ring-2>
<p className="text-center">Getting image...</p> <p className="text-center">Getting image...</p>
</> </>
)} )} */}
{(() => {
if (generateSpookyImage.data) {
if (lastSpookyImageLoaded < place - 1) {
return (
<>
<l-pulsar
size="165"
speed="1.75"
color="white"
></l-pulsar>
<p className="text-center">On queue...</p>
</>
);
}
return (
<>
<l-quantum
size="165"
speed="1.75"
color="white"
></l-quantum>
<p className="text-center">Generating...</p>
</>
);
}
return (
<>
<l-ring-2 size="165" speed="1.75" color="white"></l-ring-2>
<p className="text-center">Getting image...</p>
</>
);
})()}
</div> </div>
</div> </div>
)} )}

View File

@@ -12,7 +12,10 @@ export function Showcase({
tracksByAlbum: Record<string, any>; tracksByAlbum: Record<string, any>;
artists: any[]; artists: any[];
}) { }) {
const [spookify, setSpookify] = useState(false); const [spookify, setSpookify] = useState(true);
const [lastSpookyImageLoaded, setLastSpookyImageLoaded] = useState(0);
const albumsQuantity = Object.values(tracksByAlbum).length;
return ( return (
<> <>
<div className="flex gap-2 self-start"> <div className="flex gap-2 self-start">
@@ -24,10 +27,16 @@ export function Showcase({
<h3>Tracks by album</h3> <h3>Tracks by album</h3>
{Object.values(tracksByAlbum) {Object.values(tracksByAlbum)
.sort((a, b) => b.position - a.position) .sort((a, b) => b.position - a.position)
.map( .map((album, index) => (
(album, index) => <AlbumShowcase
!index && <AlbumShowcase spookify={spookify} {...album} />, key={album.id}
)} place={index}
lastSpookyImageLoaded={lastSpookyImageLoaded}
setLastSpookyImageLoaded={setLastSpookyImageLoaded}
spookify={spookify}
{...album}
/>
))}
<h3>Artists images</h3> <h3>Artists images</h3>
<div <div
style={{ style={{
@@ -36,9 +45,16 @@ export function Showcase({
justifyContent: "space-evenly", justifyContent: "space-evenly",
}} }}
> >
{[artists[0]].map((artist) => { {artists.map((artist, index) => {
return ( return (
<ArtistShowcase spookify={spookify} key={artist.id} {...artist} /> <ArtistShowcase
place={index + albumsQuantity}
lastSpookyImageLoaded={lastSpookyImageLoaded}
setLastSpookyImageLoaded={setLastSpookyImageLoaded}
spookify={spookify}
key={artist.id}
{...artist}
/>
); );
})} })}
</div> </div>

View File

@@ -1,8 +1,6 @@
import SpotifyWebApi from "spotify-web-api-node"; import SpotifyWebApi from "spotify-web-api-node";
import Showcase from "./showcase"; import Showcase from "./showcase";
import { FETCH_ARTISTS_LIMIT, FETCH_TRACKS_LIMIT } from "../utils/contants";
const TRACKS_LIMIT = 20;
const ARTISTS_LIMIT = 21;
export type TrackByAlbum = { export type TrackByAlbum = {
album: { album: {
@@ -35,13 +33,13 @@ export default async function SpotifyData({
const albums = albumsData.body.items; const albums = albumsData.body.items;
const artistsData = await spotifyApi.getMyTopArtists({ const artistsData = await spotifyApi.getMyTopArtists({
limit: ARTISTS_LIMIT, limit: FETCH_ARTISTS_LIMIT,
time_range: "short_term", time_range: "short_term",
}); });
const artists = artistsData.body.items; const artists = artistsData.body.items;
const tracksData = await spotifyApi.getMyTopTracks({ const tracksData = await spotifyApi.getMyTopTracks({
limit: TRACKS_LIMIT, limit: FETCH_TRACKS_LIMIT,
time_range: "short_term", time_range: "short_term",
}); });
const tracks = tracksData.body.items.map((track, i) => ({ const tracks = tracksData.body.items.map((track, i) => ({
@@ -59,7 +57,7 @@ export default async function SpotifyData({
album: track.album, album: track.album,
position: position:
tracksWithAlbum.reduce( tracksWithAlbum.reduce(
(acc, _track) => TRACKS_LIMIT / _track.position + acc, (acc, _track) => FETCH_TRACKS_LIMIT / _track.position + acc,
0, 0,
) / tracksWithAlbum.length, ) / tracksWithAlbum.length,
tracks: [], tracks: [],

View File

@@ -0,0 +1,2 @@
export const FETCH_TRACKS_LIMIT = 20;
export const FETCH_ARTISTS_LIMIT = 21;

View File

@@ -25,7 +25,10 @@ export const uploadImage = async (
}; };
export const makeImageSpooky = (publicId: string) => { export const makeImageSpooky = (publicId: string) => {
const options = { effect: "gen_background_replace" }; const options = {
effect:
"gen_background_replace:prompt_a bizarre and super creepy background acording with main object theme-max creativity",
};
try { try {
const result = cloudinary.v2.image(publicId, { ...options }); const result = cloudinary.v2.image(publicId, { ...options });