Show soundtrack covers and edit alternative names (#49)
Build / test (push) Successful in 1m43s
Build / build (push) Successful in 1m14s

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:
SansanandClaude Opus 5.5 committed 2026-10-14 22:06:30 +02:00
1 parent a735c515bf
commit ef6ac8f1fd
37 files changed
+8029 -1763

No files matched your search

+1
View File
@@ -73,6 +73,7 @@ inspector or `theme_type_variation` in code:
| `HighlightLarge`, `HighlightMedium` | Label | Orange text: sync headers and every other sync row |
| `SongRowLabel`, `SongRowLabelPlaying` | Label | A song's text, and the one that is playing |
| `TabButton` | Button | The Quiz and Statistics tabs; the chosen one is orange |
| `SoundtrackCover` | Panel | A soundtrack's cover on a statistics card and in its popup: the colour behind the initials until the cover arrives, and the rounded corners the cover is cut to |
| `StatisticsCard`, `StatisticsCardHover` | PanelContainer | A soundtrack card in the statistics, and the one under the mouse |
| `StatisticsGrid` | GridContainer | The grid of soundtrack cards, with the space between them |
| `PlayerBar` | PanelContainer | The music player's rounded bar |
+10
View File
@@ -1240,6 +1240,14 @@ content_margin_right = 10.0
content_margin_top = 4.0
content_margin_bottom = 4.0
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_soundtrackcover"]
bg_color = Color(0.361, 0.059, 0.094, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
corner_detail = 8
[resource]
default_font = ExtResource("1_default_font")
Button/colors/font_color = Color(0.478, 0.082, 0.125, 1.0)
@@ -1495,6 +1503,8 @@ StepButton/styles/disabled = SubResource("StyleBoxFlat_step_disabled")
StepButton/styles/hover = SubResource("StyleBoxFlat_step_hover")
StepButton/styles/normal = SubResource("StyleBoxFlat_step_normal")
StepButton/styles/pressed = SubResource("StyleBoxFlat_step_pressed")
SoundtrackCover/base_type = &"Panel"
SoundtrackCover/styles/panel = SubResource("StyleBoxFlat_soundtrackcover")
StatisticsCard/base_type = &"PanelContainer"
StatisticsCard/styles/panel = SubResource("StyleBoxFlat_statscard")
StatisticsCardHover/base_type = &"PanelContainer"
+10
View File
@@ -1048,6 +1048,14 @@ corner_detail = 5
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_playericon"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_soundtrackcover"]
bg_color = Color(0.22, 0.22, 0.22, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
corner_detail = 8
[resource]
default_font = ExtResource("1_default_font")
Button/colors/font_color = Color(0.875, 0.875, 0.875, 1)
@@ -1303,6 +1311,8 @@ StepButton/styles/disabled = SubResource("StyleBoxFlat_step_disabled")
StepButton/styles/hover = SubResource("StyleBoxFlat_step_hover")
StepButton/styles/normal = SubResource("StyleBoxFlat_step_normal")
StepButton/styles/pressed = SubResource("StyleBoxFlat_step_pressed")
SoundtrackCover/base_type = &"Panel"
SoundtrackCover/styles/panel = SubResource("StyleBoxFlat_soundtrackcover")
StatisticsCard/base_type = &"PanelContainer"
StatisticsCard/styles/panel = SubResource("StyleBoxFlat_statscard")
StatisticsCardHover/base_type = &"PanelContainer"
+10
View File
@@ -1223,6 +1223,14 @@ content_margin_bottom = 4.0
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_playericon"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_soundtrackcover"]
bg_color = Color(0.161, 0.341, 0.498, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
corner_detail = 8
[resource]
default_font = ExtResource("1_default_font")
Button/colors/font_color = Color(0.925, 0.937, 0.957, 1.0)
@@ -1478,6 +1486,8 @@ StepButton/styles/disabled = SubResource("StyleBoxFlat_step_disabled")
StepButton/styles/hover = SubResource("StyleBoxFlat_step_hover")
StepButton/styles/normal = SubResource("StyleBoxFlat_step_normal")
StepButton/styles/pressed = SubResource("StyleBoxFlat_step_pressed")
SoundtrackCover/base_type = &"Panel"
SoundtrackCover/styles/panel = SubResource("StyleBoxFlat_soundtrackcover")
StatisticsCard/base_type = &"PanelContainer"
StatisticsCard/styles/panel = SubResource("StyleBoxFlat_statscard")
StatisticsCardHover/base_type = &"PanelContainer"
+10
View File
@@ -1149,6 +1149,14 @@ bg_color = Color(0.2, 0.2, 0.2, 1)
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_playericon"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_soundtrackcover"]
bg_color = Color(0.259, 0.259, 0.259, 1)
corner_radius_top_left = 8
corner_radius_top_right = 8
corner_radius_bottom_right = 8
corner_radius_bottom_left = 8
corner_detail = 8
[resource]
default_font = ExtResource("1_default_font")
Button/colors/font_color = Color(1, 0.612, 0, 1)
@@ -1404,6 +1412,8 @@ StepButton/styles/disabled = SubResource("StyleBoxFlat_step_disabled")
StepButton/styles/hover = SubResource("StyleBoxFlat_step_hover")
StepButton/styles/normal = SubResource("StyleBoxFlat_step_normal")
StepButton/styles/pressed = SubResource("StyleBoxFlat_step_pressed")
SoundtrackCover/base_type = &"Panel"
SoundtrackCover/styles/panel = SubResource("StyleBoxFlat_soundtrackcover")
StatisticsCard/base_type = &"PanelContainer"
StatisticsCard/styles/panel = SubResource("StyleBoxFlat_statscard")
StatisticsCardHover/base_type = &"PanelContainer"