fix(share): use Qobuz track URL for song.link instead of ISRC
Odesli API doesn't support direct ISRC lookup. Changed to use Qobuz track URL (https://open.qobuz.com/track/{id}) which Odesli can properly resolve to song.link.
This commit is contained in:
1 parent
2efa107aa7
commit
657682fc5e
3 files changed
+21
-46
No files matched your search
@@ -2,29 +2,20 @@
|
||||
|
||||
use tauri::State;
|
||||
|
||||
use crate::share::{ShareError, SongLinkClient, SongLinkResponse};
|
||||
use crate::share::{ShareError, SongLinkResponse};
|
||||
use crate::AppState;
|
||||
|
||||
/// Get song.link URL for a track
|
||||
/// Requires ISRC to be present in the track metadata
|
||||
/// Get song.link URL for a track using Qobuz track ID
|
||||
#[tauri::command]
|
||||
pub async fn share_track_songlink(
|
||||
isrc: Option<String>,
|
||||
track_id: u64,
|
||||
state: State<'_, AppState>,
|
||||
) -> Result<SongLinkResponse, String> {
|
||||
let isrc = isrc.ok_or_else(|| {
|
||||
ShareError::MissingIsrc.to_string()
|
||||
})?;
|
||||
|
||||
if isrc.is_empty() {
|
||||
return Err(ShareError::MissingIsrc.to_string());
|
||||
}
|
||||
|
||||
log::info!("Command: share_track_songlink ISRC={}", isrc);
|
||||
log::info!("Command: share_track_songlink track_id={}", track_id);
|
||||
|
||||
state
|
||||
.songlink
|
||||
.get_by_isrc(&isrc)
|
||||
.get_by_track_id(&track_id.to_string())
|
||||
.await
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
@@ -48,22 +48,24 @@ impl SongLinkClient {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get song.link URL for a track by ISRC
|
||||
pub async fn get_by_isrc(&self, isrc: &str) -> Result<SongLinkResponse, ShareError> {
|
||||
let cache_key = format!("isrc:{}", isrc);
|
||||
/// Get song.link URL for a track by Qobuz track ID
|
||||
pub async fn get_by_track_id(&self, track_id: &str) -> Result<SongLinkResponse, ShareError> {
|
||||
let cache_key = format!("track:{}", track_id);
|
||||
|
||||
// Check cache first
|
||||
if let Some(cached) = self.get_from_cache(&cache_key) {
|
||||
log::debug!("Cache hit for ISRC: {}", isrc);
|
||||
log::debug!("Cache hit for track ID: {}", track_id);
|
||||
return Ok(cached);
|
||||
}
|
||||
|
||||
log::info!("Fetching song.link for ISRC: {}", isrc);
|
||||
// Use Qobuz track URL for Odesli lookup
|
||||
let qobuz_url = format!("https://open.qobuz.com/track/{}", track_id);
|
||||
log::info!("Fetching song.link for Qobuz track: {}", qobuz_url);
|
||||
|
||||
let response = self
|
||||
.client
|
||||
.get(ODESLI_API_URL)
|
||||
.query(&[("isrc", isrc), ("userCountry", "US")])
|
||||
.query(&[("url", &qobuz_url), ("userCountry", &"US".to_string())])
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
@@ -77,7 +79,7 @@ impl SongLinkClient {
|
||||
}
|
||||
|
||||
let odesli: OdesliResponse = response.json().await?;
|
||||
let result = self.convert_response(odesli, isrc.to_string(), ContentType::Track)?;
|
||||
let result = self.convert_response(odesli, track_id.to_string(), ContentType::Track)?;
|
||||
|
||||
// Cache the result
|
||||
self.store_in_cache(cache_key, result.clone());
|
||||
|
||||
+7
-25
@@ -472,28 +472,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveTrackIsrc(trackId: number, isrc?: string): Promise<string | null> {
|
||||
if (isrc && isrc.trim()) {
|
||||
return isrc;
|
||||
}
|
||||
try {
|
||||
const fullTrack = await invoke<QobuzTrack>('get_track', { trackId });
|
||||
return fullTrack.isrc || null;
|
||||
} catch (err) {
|
||||
console.error('Failed to fetch track ISRC:', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function shareSonglinkTrack(trackId: number, isrc?: string) {
|
||||
const resolvedIsrc = await resolveTrackIsrc(trackId, isrc);
|
||||
if (!resolvedIsrc) {
|
||||
showToast('ISRC not available for this track', 'error');
|
||||
return;
|
||||
}
|
||||
async function shareSonglinkTrack(trackId: number) {
|
||||
try {
|
||||
showToast('Fetching Song.link...', 'info');
|
||||
const response = await invoke<SongLinkResponse>('share_track_songlink', { isrc: resolvedIsrc });
|
||||
const response = await invoke<SongLinkResponse>('share_track_songlink', { trackId });
|
||||
await copyToClipboard(response.pageUrl, 'Song.link copied');
|
||||
} catch (err) {
|
||||
console.error('Failed to get Song.link:', err);
|
||||
@@ -1422,7 +1404,7 @@
|
||||
onTrackAddFavorite={addTrackToFavorites}
|
||||
onTrackAddToPlaylist={(trackId) => openAddToPlaylist([trackId])}
|
||||
onTrackShareQobuz={shareQobuzTrackLink}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id, track.isrc)}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id)}
|
||||
onTrackGoToAlbum={handleAlbumClick}
|
||||
onTrackGoToArtist={handleArtistClick}
|
||||
onArtistClick={handleArtistClick}
|
||||
@@ -1444,7 +1426,7 @@
|
||||
onTrackPlayLater={handleAlbumTrackPlayLater}
|
||||
onTrackAddFavorite={addTrackToFavorites}
|
||||
onTrackShareQobuz={shareQobuzTrackLink}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id, track.isrc)}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id)}
|
||||
onTrackGoToAlbum={handleAlbumClick}
|
||||
onTrackGoToArtist={handleArtistClick}
|
||||
onPlayAll={handlePlayAllAlbum}
|
||||
@@ -1463,7 +1445,7 @@
|
||||
onTrackAddFavorite={addTrackToFavorites}
|
||||
onTrackAddToPlaylist={(trackId) => openAddToPlaylist([trackId])}
|
||||
onTrackShareQobuz={shareQobuzTrackLink}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id, track.isrc)}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id)}
|
||||
onTrackGoToAlbum={handleAlbumClick}
|
||||
onTrackGoToArtist={handleArtistClick}
|
||||
/>
|
||||
@@ -1484,7 +1466,7 @@
|
||||
onTrackAddFavorite={addTrackToFavorites}
|
||||
onTrackAddToPlaylist={(trackId) => openAddToPlaylist([trackId])}
|
||||
onTrackShareQobuz={shareQobuzTrackLink}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id, track.isrc)}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id)}
|
||||
onTrackGoToAlbum={handleAlbumClick}
|
||||
onTrackGoToArtist={handleArtistClick}
|
||||
/>
|
||||
@@ -1498,7 +1480,7 @@
|
||||
onTrackAddFavorite={addTrackToFavorites}
|
||||
onTrackAddToPlaylist={(trackId) => openAddToPlaylist([trackId])}
|
||||
onTrackShareQobuz={shareQobuzTrackLink}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id, track.isrc)}
|
||||
onTrackShareSonglink={(track) => shareSonglinkTrack(track.id)}
|
||||
onTrackGoToAlbum={handleAlbumClick}
|
||||
onTrackGoToArtist={handleArtistClick}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user