feat(lastfm): improve auth flow with embedded credentials support

- Add support for build-time credentials via LASTFM_API_KEY/LASTFM_API_SECRET env vars
- Add lastfm_has_embedded_credentials command to check for embedded keys
- Add lastfm_open_auth_url command to open browser via native opener
- Simplify UI flow: if embedded credentials exist, just click Connect
- Add cancel button during authorization flow
- Clean up UI when waiting for user to authorize in browser
This commit is contained in:
vicrodh committed 2026-01-09 13:02:05 -06:00
1 parent 480594c03c
commit 19bad7200b
5 files changed
+112 -49

No files matched your search

+3
View File
@@ -55,6 +55,9 @@ souvlaki = "0.7"
# Desktop notifications
notify-rust = "4"
# URL opening
open = "5"
# Storage
# sled = "0.34"
+14 -2
View File
@@ -2,16 +2,28 @@
use tauri::State;
use crate::lastfm::LastFmSession;
use crate::lastfm::{LastFmClient, LastFmSession};
use crate::AppState;
/// Check if Last.fm has API credentials configured
/// Check if Last.fm has embedded (build-time) credentials
#[tauri::command]
pub fn lastfm_has_embedded_credentials() -> bool {
LastFmClient::has_embedded_credentials()
}
/// Check if Last.fm has API credentials configured (embedded or user-provided)
#[tauri::command]
pub async fn lastfm_has_credentials(state: State<'_, AppState>) -> Result<bool, String> {
let client = state.lastfm.lock().await;
Ok(client.has_credentials())
}
/// Open a URL in the default browser
#[tauri::command]
pub async fn lastfm_open_auth_url(url: String) -> Result<(), String> {
open::that(&url).map_err(|e| format!("Failed to open browser: {}", e))
}
/// Set Last.fm API credentials
#[tauri::command]
pub async fn lastfm_set_credentials(
+16 -5
View File
@@ -9,10 +9,11 @@ use std::collections::BTreeMap;
const LASTFM_API_URL: &str = "https://ws.audioscrobbler.com/2.0/";
// Last.fm API credentials - users need to create their own app at https://www.last.fm/api/account/create
// For now using placeholder - in production this should be configurable or use OAuth
const API_KEY: &str = ""; // User must set this
const API_SECRET: &str = ""; // User must set this
// Last.fm API credentials
// Set via environment variables at build time, or users can enter their own
// To set: LASTFM_API_KEY=xxx LASTFM_API_SECRET=yyy cargo build
const DEFAULT_API_KEY: Option<&str> = option_env!("LASTFM_API_KEY");
const DEFAULT_API_SECRET: Option<&str> = option_env!("LASTFM_API_SECRET");
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LastFmSession {
@@ -48,7 +49,17 @@ pub struct LastFmClient {
impl Default for LastFmClient {
fn default() -> Self {
Self::new(API_KEY.to_string(), API_SECRET.to_string())
Self::new(
DEFAULT_API_KEY.unwrap_or("").to_string(),
DEFAULT_API_SECRET.unwrap_or("").to_string(),
)
}
}
impl LastFmClient {
/// Check if embedded (build-time) credentials are available
pub fn has_embedded_credentials() -> bool {
DEFAULT_API_KEY.is_some() && DEFAULT_API_SECRET.is_some()
}
}
+2
View File
@@ -141,10 +141,12 @@ pub fn run() {
commands::get_cache_stats,
commands::clear_cache,
// Last.fm commands
commands::lastfm_has_embedded_credentials,
commands::lastfm_has_credentials,
commands::lastfm_set_credentials,
commands::lastfm_is_authenticated,
commands::lastfm_get_auth_url,
commands::lastfm_open_auth_url,
commands::lastfm_authenticate,
commands::lastfm_set_session,
commands::lastfm_disconnect,