Show soundtrack covers and edit alternative names (#49)
Covers: statistics cards show the soundtrack's cover on the left, and the
statistics popup shows it large. Until it arrives, and without a cover, the
soundtrack's initials stand in. Covers load only for cards on or near the
screen, three at a time, and are cached in covers/ next to the settings
(CoverCache), downloaded again only when cover_modified changes. The index and
file handling are shared with CharacterCache in a new FileCache.
Alternative names: the popup shows them and has an editor (add, remove, save)
that sends PUT /soundtracks/{uuid}/alternative-names. The statistics search and
the Search popup find soundtracks by them; Search shows the matching name after
the real one. Search now loads /soundtracks, falling back to the plain list.
The API types are regenerated from the server's spec, with a SoundtrackCover
theme style in every theme.
Closes #49
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
a735c515bf
commit
ef6ac8f1fd
37 files changed
+8029
-1763
No files matched your search
@@ -131,6 +131,31 @@ func fetch_soundtracks(on_done: Callable, on_failed: Callable = Callable()) -> v
|
||||
get_json_list("/soundtracks", Soundtrack, on_done, on_failed)
|
||||
|
||||
|
||||
## Downloads the cover picture of the soundtrack with [param uuid] as bytes (JPEG or
|
||||
## PNG). The server answers 404 while it has no cover for it.
|
||||
func fetch_soundtrack_cover(
|
||||
uuid: String, on_done: Callable, on_failed: Callable = Callable()) -> void:
|
||||
get_bytes("/soundtracks/%s/cover" % uuid.uri_encode(), on_done, on_failed)
|
||||
|
||||
|
||||
## Replaces the alternative names of the soundtrack with [param uuid] with
|
||||
## [param names]. The server trims them, drops duplicates and the soundtrack's own name,
|
||||
## and calls [param on_done] with the updated [Soundtrack].
|
||||
func set_alternative_names(uuid: String, names: Array[String], on_done: Callable,
|
||||
on_failed: Callable = Callable()) -> void:
|
||||
var request: AlternativeNames = AlternativeNames.new()
|
||||
request.names = names
|
||||
var path: String = "/soundtracks/%s/alternative-names" % uuid.uri_encode()
|
||||
var saved: Callable = func saved(data: Variant) -> void:
|
||||
if !(data is Dictionary):
|
||||
push_warning("Expected a JSON object from " + path)
|
||||
_call_if_valid(on_failed)
|
||||
return
|
||||
on_done.call(Soundtrack.from_dict(data))
|
||||
_request(path, HTTPClient.METHOD_PUT, _parse_json.bind(path, saved, on_failed), on_failed,
|
||||
true, JSON.stringify(request.to_dict()))
|
||||
|
||||
|
||||
## Fetches a soundtrack and its songs as a [SoundtrackWithSongList].
|
||||
func fetch_soundtrack(
|
||||
uuid: String, on_done: Callable, on_failed: Callable = Callable()) -> void:
|
||||
@@ -419,13 +444,14 @@ func _parse_json(
|
||||
|
||||
|
||||
# Sends the request with the token, and once more with a new token if the server
|
||||
# answers 401
|
||||
# answers 401. A [param json_body] is sent as the request's body.
|
||||
func _request(
|
||||
path: String,
|
||||
method: int,
|
||||
on_success: Callable,
|
||||
on_failed: Callable,
|
||||
may_retry: bool = true,
|
||||
json_body: String = "",
|
||||
) -> void:
|
||||
_with_token(func(token: String) -> void:
|
||||
_send(path, method, token, func(response_code: int, body: PackedByteArray) -> void:
|
||||
@@ -433,10 +459,10 @@ func _request(
|
||||
GameLog.debug("Token refused by the server, getting a new one")
|
||||
if _token == token:
|
||||
clear_token()
|
||||
_request(path, method, on_success, on_failed, false)
|
||||
_request(path, method, on_success, on_failed, false, json_body)
|
||||
return
|
||||
_handle_response(path, response_code, body, on_success, on_failed)
|
||||
)
|
||||
, json_body)
|
||||
, on_failed)
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user