diff --git a/src/components/Album.tsx b/src/components/Album.tsx
index d943d7a..a5ada66 100644
--- a/src/components/Album.tsx
+++ b/src/components/Album.tsx
@@ -1,5 +1,5 @@
import { useEffect, useState } from 'react'
-import { getTracks } from 'utils/search'
+import { getDownloadUrl, getTracks } from 'utils/search'
import type { AlbumRow, TrackRow } from 'utils/types'
import Loader from './Loader'
@@ -49,13 +49,13 @@ function TrackList(props: { url: string; open: boolean; lastReqRef: React.RefObj
{tracks && open ? (
{tracks.map((t, i) => (
-
+
{(i + 1).toString().padStart(2, '0').slice(-2)}.
{t.name}
FLAC/MP3
-
+
))}
@@ -65,5 +65,27 @@ function TrackList(props: { url: string; open: boolean; lastReqRef: React.RefObj
}
function TrackDownload(props: { url: string; lastReqRef: React.RefObject
}) {
- return
+ const { url, lastReqRef } = props
+ const [downloadUrl, setDownloadUrl] = useState()
+ const [loading, setLoading] = useState(false)
+
+ async function fetchUrl() {
+ try {
+ setLoading(true)
+ const dlUrl = await getDownloadUrl(url, lastReqRef)
+ setDownloadUrl(dlUrl)
+ } finally {
+ setLoading(false)
+ }
+ }
+
+ return downloadUrl ? (
+
+ Download
+
+ ) : (
+
+ )
}
diff --git a/src/components/Downloader.tsx b/src/components/Downloader.tsx
index 13feb1c..9f2aaaa 100644
--- a/src/components/Downloader.tsx
+++ b/src/components/Downloader.tsx
@@ -53,8 +53,8 @@ export default function Downloader() {
) : null}
- {results.map((r) => (
-
+ {results.map((r, i) => (
+
))}
>
diff --git a/src/pages/index.astro b/src/pages/index.astro
index c7ad26f..a4a7a43 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -117,6 +117,7 @@ import Downloader from '../components/Downloader'
border-radius: 4px;
cursor: pointer;
transition: background 0.2s;
+ font-size: 13px;
}
.download-btn:hover {
background-color: #218838;
@@ -153,12 +154,20 @@ import Downloader from '../components/Downloader'
display: flex;
gap: 8px;
}
+ a.download-btn {
+ text-decoration: none;
+ }
.download-btn.flac {
background-color: #6f42c1;
}
.download-btn.flac:hover {
background-color: #563d7c;
}
+ .download-btn .loader {
+ height: 8px;
+ width: 8px;
+ margin: 2px 8px;
+ }
.results h3 {
margin: 0;
font-size: 1.1em;
diff --git a/src/utils/search.ts b/src/utils/search.ts
index 4679e0a..0c87b44 100644
--- a/src/utils/search.ts
+++ b/src/utils/search.ts
@@ -75,3 +75,31 @@ export async function getTracks(url: string, lastReqRef: React.RefObject
return tracks
}
+
+export async function getDownloadUrl(trackPageUrl: string, lastReqRef: React.RefObject) {
+ const trackPageHtml = await (await politeFetch(trackPageUrl, lastReqRef)).text()
+ const $ = cheerio.load(trackPageHtml)
+
+ const audioLinks: string[] = []
+
+ $('a[href$=".mp3"], a[href$=".flac"]').each((index, link) => {
+ let href = $(link).attr('href')
+ if (!href) return
+
+ href = decodeURIComponent(href)
+ if (!href.startsWith('http')) {
+ href = `https://downloads.khinsider.com${href}`
+ }
+ audioLinks.push(href)
+ })
+
+ const flacLinks = audioLinks.filter((link) => link.endsWith('.flac'))
+ if (flacLinks.length > 0) {
+ return flacLinks[0]
+ }
+
+ const mp3Links = audioLinks.filter((link) => link.endsWith('.mp3'))
+ if (mp3Links.length > 0) {
+ return mp3Links[0]
+ }
+}