mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-30 21:29:36 +02:00
feat(concerts): show artwork-themed event details in app
This commit is contained in:
1 parent
ab58cdbb0c
commit
abb8dc4a42
18 files changed
+1047
-23
No files matched your search
@@ -185,6 +185,7 @@ impl Backend {
|
||||
"album" => "getAlbum",
|
||||
"playlist" => "getPlaylist",
|
||||
"artist" => "getArtist",
|
||||
"concert" => "getConcert",
|
||||
_ => {
|
||||
return Err(ResolverError::Failed(format!(
|
||||
"unsupported provider resource type: {kind}"
|
||||
@@ -393,6 +394,7 @@ fn response(kind: &str, value: &Value, check: &Check<'_>) -> Result<Value, Resol
|
||||
check().map_err(ResolverError::Cancelled)?;
|
||||
let cover = text(value, "cover_url");
|
||||
Ok(match kind {
|
||||
"concert" => json!({"concert": value}),
|
||||
// Move normalized values into the envelope. json! serializes borrowed
|
||||
// expressions, duplicating every field of an already-built track list.
|
||||
"track" => Map::from_iter([("track".into(), track(value, "", 0))]).into(),
|
||||
|
||||
@@ -21,11 +21,19 @@ function getArtist(id) {
|
||||
return {id, name: "Example Artist", image_url: "https://example.invalid/portrait.jpg",
|
||||
concerts: id === "bad-concerts" ? {} : [{id: "event-1", location: "Example City",
|
||||
venue: "Example Hall", startAt: "2026-10-07T01:00:00Z", timeZone: "America/New_York",
|
||||
url: "https://example.invalid/events/1"}],
|
||||
url: "https://example.invalid/events/1", detailId: "event-1"}],
|
||||
headerLogo: "https://example.invalid/logo.png", albumsNext: "artist-page-2", albums: []};
|
||||
}
|
||||
function handleUrl() { return {type: "artist", artist: getArtist("artist-1")}; }
|
||||
registerExtension({getAlbum: collection, getPlaylist: collection, getArtist, handleUrl});
|
||||
function getConcert(id) {
|
||||
return {id, artistName: "Example Artist", title: "Example Show", venue: "Example Hall",
|
||||
address: "123 Example Street", startAt: "2026-10-07T01:00:00Z",
|
||||
endAt: "2026-10-07T04:00:00Z", timeZone: "America/New_York",
|
||||
ticketUrl: "https://example.invalid/tickets/1", mapUrl: "https://example.invalid/maps/1",
|
||||
coverUrl: "https://example.invalid/artist.jpg", attribution: "Example Events",
|
||||
setList: {id: "list-1", name: "Concert Set List", coverUrl: "https://example.invalid/list.jpg"}};
|
||||
}
|
||||
registerExtension({getAlbum: collection, getPlaylist: collection, getArtist, getConcert, handleUrl});
|
||||
"#;
|
||||
|
||||
fn fixture() -> (tempfile::TempDir, Backend) {
|
||||
@@ -54,6 +62,30 @@ fn fixture() -> (tempfile::TempDir, Backend) {
|
||||
(root, backend)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn concert_details_preserve_generic_actions_and_set_list() {
|
||||
let (_root, backend) = fixture();
|
||||
let result: Value = serde_json::from_str(
|
||||
&backend
|
||||
.get_provider_metadata_json(ID, "concert", "event-1", &|| Ok(()))
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap();
|
||||
let detail = &result["concert"];
|
||||
assert_eq!(detail["id"], "event-1");
|
||||
assert_eq!(detail["artist_name"], "Example Artist");
|
||||
assert_eq!(detail["start_at"], "2026-10-07T01:00:00Z");
|
||||
assert_eq!(detail["end_at"], "2026-10-07T04:00:00Z");
|
||||
assert_eq!(detail["ticket_url"], "https://example.invalid/tickets/1");
|
||||
assert_eq!(detail["map_url"], "https://example.invalid/maps/1");
|
||||
assert_eq!(detail["set_list"]["id"], "list-1");
|
||||
assert_eq!(
|
||||
detail["set_list"]["cover_url"],
|
||||
"https://example.invalid/list.jpg"
|
||||
);
|
||||
assert_eq!(detail["attribution"], "Example Events");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_envelopes_preserve_json_and_cancellation() {
|
||||
let value = json!({
|
||||
|
||||
@@ -214,8 +214,8 @@ impl ExtensionManager {
|
||||
let manifest = &entry.manifest;
|
||||
let requirement =
|
||||
match method {
|
||||
"getTrack" | "getAlbum" | "getPlaylist" | "getArtist" | "searchTracks"
|
||||
| "enrichTrack" => (!manifest.has_type("metadata_provider"))
|
||||
"getTrack" | "getAlbum" | "getPlaylist" | "getArtist" | "getConcert"
|
||||
| "searchTracks" | "enrichTrack" => (!manifest.has_type("metadata_provider"))
|
||||
.then_some("is not a metadata provider"),
|
||||
"checkAvailability" => (!manifest.has_type("download_provider"))
|
||||
.then_some("is not a download provider"),
|
||||
@@ -313,6 +313,7 @@ impl ExtensionManager {
|
||||
"getAlbum" => "album",
|
||||
"getPlaylist" => "playlist",
|
||||
"getArtist" => "artist",
|
||||
"getConcert" => "concert",
|
||||
"handleUrl" => "URL handle result",
|
||||
"fetchLyrics" => "lyrics result",
|
||||
"checkAvailability" => "availability result",
|
||||
|
||||
@@ -208,7 +208,18 @@
|
||||
function concert(value) {
|
||||
return fields(value, [["id","s"],["location","s"],["venue","s"],
|
||||
["start_at","s","startAt"],["time_zone","s","timeZone"],
|
||||
["url","s"]], ["id","location","start_at"]);
|
||||
["url","s"],["detail_id","s","detailId"]], ["id","location","start_at"]);
|
||||
}
|
||||
function concertDetail(value) {
|
||||
const result = fields(value, [["id","s"],["artist_name","s","artistName"],
|
||||
["title","s"],["cover_url","s","coverUrl"],["venue","s"],["address","s"],
|
||||
["start_at","s","startAt"],["end_at","s","endAt"],["time_zone","s","timeZone"],
|
||||
["ticket_url","s","ticketUrl"],["map_url","s","mapUrl"],["url","s"],
|
||||
["attribution","s"]], ["id"]);
|
||||
const setList = first(object(value), ["set_list","setList"]);
|
||||
if (!empty(setList)) result.set_list = fields(setList, [["id","s"],["name","s"],
|
||||
["cover_url","s","coverUrl"],["url","s"]], ["id","name"]);
|
||||
return result;
|
||||
}
|
||||
function decryption(value) {
|
||||
if (empty(value)) return null;
|
||||
@@ -274,6 +285,7 @@
|
||||
}
|
||||
const parsers = {
|
||||
getTrack: track, enrichTrack: track, getAlbum: album, getPlaylist: album, getArtist: artist,
|
||||
getConcert: concertDetail,
|
||||
searchTracks: search, customSearch: value => array(value, track), handleUrl: url,
|
||||
checkAvailability: value => fields(value, [["available","b"],["reason","s"],["track_id","s","trackId"],
|
||||
["skip_fallback","b","skipFallback"],["prepared_context","m","preparedContext"]], ["available"]),
|
||||
|
||||
Reference in new issue
Block a user