feat: add notification history dropdown and track fetching

- Add notifications dropdown in topbar with click-to-expand details
- Implement GetAlbum gRPC call for fetching track details
- Add track caching to avoid duplicate requests
- Guard against albums with empty IDs from server
- Increase notification TTL from 4s to 6s
- Add grpcurl to flake.nix for debugging
This commit is contained in:
Alexander
2026-05-09 11:19:24 +02:00
parent e77e854d2e
commit f7660436c2
13 changed files with 508 additions and 139 deletions
+25 -1
View File
@@ -3,16 +3,21 @@ use tonic::transport::Channel;
use crate::proto::music_agregator_v1::music_agregator_service_client::MusicAgregatorServiceClient;
pub use crate::proto::music_agregator_v1::{AlbumDetail, ArtistSummary, GetArtistsRequest};
pub use crate::proto::music_agregator_v1::{
AlbumDetail, ArtistSummary, GetAlbumRequest, GetArtistsRequest, TrackDetail,
};
#[derive(Debug)]
pub enum GrpcRequest {
GetArtists,
GetAlbum { album_id: String },
}
#[derive(Debug)]
#[allow(dead_code, clippy::large_enum_variant)]
pub enum GrpcResponse {
Artists(Vec<ArtistSummary>),
Album { album: AlbumDetail, tracks: Vec<TrackDetail> },
Error(String),
}
@@ -36,6 +41,21 @@ impl GrpcClient {
let response = self.music.get_artists(GetArtistsRequest {}).await?;
Ok(response.into_inner().artists)
}
pub async fn get_album(
&mut self,
album_id: String,
) -> Result<(AlbumDetail, Vec<TrackDetail>), tonic::Status> {
let response = self
.music
.get_album(GetAlbumRequest { album_id })
.await?;
let inner = response.into_inner();
let album = inner.album.ok_or_else(|| {
tonic::Status::not_found("Album not found in response")
})?;
Ok((album, inner.tracks))
}
}
pub fn spawn_grpc_worker(
@@ -61,6 +81,10 @@ pub fn spawn_grpc_worker(
Ok(artists) => GrpcResponse::Artists(artists),
Err(e) => GrpcResponse::Error(e.to_string()),
},
GrpcRequest::GetAlbum { album_id } => match client.get_album(album_id).await {
Ok((album, tracks)) => GrpcResponse::Album { album, tracks },
Err(e) => GrpcResponse::Error(e.to_string()),
}
};
if resp_tx.send(response).await.is_err() {