Add a soundtrack by picking or dropping a folder (#50)
Build / test (pull_request) Successful in 2m3s
Build / build (pull_request) Skipped

"Add soundtrack…" in the statistics toolbar, or a folder dropped anywhere on
the window, opens a popup that lists the folder's songs and uploads them to
the server, which adds the soundtrack at once (Sansan/MusicServer#33).

- The name comes from the folder and can be changed; characters the server
  refuses are replaced.
- Only MP3s are uploaded, as the server takes no other; other song files
  are listed greyed out as left out. Hidden files are skipped.
- Disc folders are flattened with the disc's number first ("1-01 Title.mp3"),
  as the server wants one folder. With one disc folder, names stay as
  they are.
- Songs are sent one at a time with a progress bar, reading one file at a
  time. A failed song is sent again twice, then the upload is cancelled
  and the server's reason shown. Closing the popup cancels it too.
- Not offered while the server syncs, offline, or without MP3s.
- Afterwards search, the inspiration list and the statistics reload.

The API types come from the server's spec (Upload, UploadFile,
UploadRequest).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
SansanandClaude Opus 5.5 committed 2026-10-15 21:43:59 +02:00
1 parent f39865fffc
commit c86dacb890
25 files changed
+3306 -4314

No files matched your search

+28 -1
View File
@@ -21,6 +21,7 @@ var popup_backdrop: PopupBackdrop
@onready var log_popup: LogPopup = %LogPopup
@onready var settings_popup: SettingsPopup = %SettingsPopup
@onready var update_popup: UpdatePopup = %UpdatePopup
@onready var upload_popup: UploadPopup = %UploadPopup
@onready var statistics_view: StatisticsView = $StatisticsView
@onready var soundtrack_stats_popup: SoundtrackStatsPopup = $SoundtrackStatsPopup
@@ -40,6 +41,9 @@ func _ready() -> void:
top_bar.settings_pressed.connect(settings_popup.open)
top_bar.update_pressed.connect(update_popup.show_update)
update_popup.restarting.connect(quiz.save_now)
statistics_view.add_soundtrack_pressed.connect(upload_popup.choose_folder)
upload_popup.soundtrack_added.connect(_on_soundtrack_added)
get_window().files_dropped.connect(on_files_dropped)
settings_popup.server_changed.connect(quiz.on_server_changed)
settings_popup.characters_changed.connect(quiz.character_select_popup.load_characters)
settings_popup.clear_cache_requested.connect(clear_cache)
@@ -78,6 +82,29 @@ func clear_cache() -> void:
quiz.character_select_popup.load_characters()
## Offers to upload a folder dropped on the window as a new soundtrack. Dropped songs
## stand for the folder they are in.
func on_files_dropped(paths: PackedStringArray) -> void:
if paths.is_empty():
return
var folder: String = paths[0]
for path: String in paths:
if DirAccess.dir_exists_absolute(path):
folder = path
break
if !DirAccess.dir_exists_absolute(folder):
folder = folder.get_base_dir()
upload_popup.show_folder(folder)
# A new soundtrack is found by search, listed for inspiration and in the statistics
func _on_soundtrack_added(_soundtrack: SoundtrackWithSongList) -> void:
search_popup.get_list_of_soundtracks()
quiz.inspiration_list.load_soundtracks()
if statistics_view.visible:
statistics_view.refresh()
# The quiz finds a soundtrack's cover by the cover times in the soundtrack list
func _remember_cover_times(soundtracks: Array[Soundtrack]) -> void:
var times: Dictionary = {}
@@ -116,7 +143,7 @@ func _input(event: InputEvent) -> void:
func _popups() -> Array[BasePopup]:
return [search_popup, sync_popup, qr_popup, shortcuts_popup, about_popup, log_popup,
soundtrack_stats_popup, settings_popup, update_popup]
soundtrack_stats_popup, settings_popup, update_popup, upload_popup]
# How many songs to download ahead can be changed in the settings. Waiting until the