diff --git a/src/equicordplugins/songLink.desktop/SongLinker.tsx b/src/equicordplugins/songLink.desktop/SongLinker.tsx index 158baad3d..decc26843 100644 --- a/src/equicordplugins/songLink.desktop/SongLinker.tsx +++ b/src/equicordplugins/songLink.desktop/SongLinker.tsx @@ -12,19 +12,28 @@ import { Button, useEffect, useState } from "@webpack/common"; import pl, { Native, settings, SongLinkResult } from "."; import { Providers } from "./Providers"; -export default function SongLinker({ url }: { url: string; }) { +interface SongLinkerProps { + url: string; + onResolved?: (url: string, result: SongLinkResult) => void; +} + +export default function SongLinker({ url, onResolved }: SongLinkerProps) { const [songData, setSongData] = useState(); useEffect(() => { async function doStuff() { - if (pl.cache[url]) return void setSongData(pl.cache[url]); - - const sd = await Native.getTrackData(url); + let sd: SongLinkResult; + if (pl.cache[url]) { + sd = pl.cache[url]; + } else { + sd = await Native.getTrackData(url); + pl.addToCache(url, sd); + } setSongData(sd); - pl.addToCache(url, sd); + onResolved?.(url, sd); } doStuff(); - }); + }, [url]); return { diff --git a/src/equicordplugins/songLink.desktop/index.tsx b/src/equicordplugins/songLink.desktop/index.tsx index f558083a0..801ab12ff 100644 --- a/src/equicordplugins/songLink.desktop/index.tsx +++ b/src/equicordplugins/songLink.desktop/index.tsx @@ -9,6 +9,7 @@ import { definePluginSettings } from "@api/Settings"; import { Devs, EquicordDevs } from "@utils/constants"; import { sendMessage } from "@utils/discord"; import definePlugin, { OptionType, PluginNative } from "@utils/types"; +import { useEffect, useState } from "@webpack/common"; import { Providers } from "./Providers"; import { Settings } from "./Settings"; @@ -83,6 +84,43 @@ function formatMessage(data: SongLinkResult): string | null { return parts.join("\n"); } +function SongLinkerList({ urls }: { urls: string[]; }) { + const [resolvedKeys, setResolvedKeys] = useState>( + () => Object.fromEntries(urls.map(u => [u, null])) + ); + + useEffect(() => { + setResolvedKeys(Object.fromEntries(urls.map(u => [u, null]))); + }, [urls.join("\n")]); + + function onResolved(url: string, result: SongLinkResult) { + const key = result.info + ? `${result.info.title}\0${result.info.artist}` + : url; + setResolvedKeys(prev => prev[url] === key ? prev : { ...prev, [url]: key }); + } + + const seenKeys = new Set(); + const dedupedUrls = urls.filter(url => { + const key = resolvedKeys[url]; + if (key === null) return true; + if (seenKeys.has(key)) return false; + seenKeys.add(key); + return true; + }); + + return
+ {dedupedUrls.map(url => ( + + ))} +
; +} + export default definePlugin({ name: "SongLink", description: "Adds streaming service buttons below song links", @@ -107,19 +145,12 @@ export default definePlugin({ /https:\/\/music\.youtube\.com\/watch\?v=[0-9A-Za-z_-]+/, // yt music /https:\/\/tidal\.com\/track\/[0-9]+\/u/ // tidal ]; - const musicLinks = content.match(new RegExp(regexes.map(r => r.source).join("|"), "g")); - if (!musicLinks?.length) return; + const allMatches = content.match(new RegExp(regexes.map(r => r.source).join("|"), "g")); + if (!allMatches?.length) return; - return
- { - musicLinks.map(item => ) - } -
; + const musicLinks = [...new Set(allMatches)]; + + return ; }, commands: [ {