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
@@ -5,23 +5,36 @@ extends RefCounted
|
||||
## letters also find the letters in order with others in between.
|
||||
##
|
||||
## Used by the Search popup and the statistics view, so both find the same soundtracks.
|
||||
##
|
||||
## A soundtrack is also found by its alternative names, e.g. "FF7" for "Final Fantasy
|
||||
## VII". The results are always the real names; [method matched_alternative] tells which
|
||||
## alternative name matched.
|
||||
|
||||
## Each name as a Dictionary with its original, lowercase and cleaned form.
|
||||
## Each searchable name as a Dictionary: the soundtrack's real name ("original"), the name
|
||||
## searched in ("text"), and its lowercase and cleaned forms.
|
||||
var _names: Array[Dictionary] = []
|
||||
# The alternative name that matched in the last search, by real name
|
||||
var _matched_alternatives: Dictionary = {}
|
||||
|
||||
## Compiled patterns for the letters-in-order search, by cleaned search term.
|
||||
var _regex_cache: Dictionary = {}
|
||||
|
||||
|
||||
## Replaces the names to search in.
|
||||
func set_names(names: Array) -> void:
|
||||
## Replaces the names to search in. [param alternatives] has the other names of a
|
||||
## soundtrack, by its real name.
|
||||
func set_names(names: Array, alternatives: Dictionary = {}) -> void:
|
||||
_names.clear()
|
||||
_matched_alternatives.clear()
|
||||
for soundtrack: String in names:
|
||||
_names.append({
|
||||
"original": soundtrack,
|
||||
"lowercase": soundtrack.to_lower(),
|
||||
"cleaned": clean_term(soundtrack),
|
||||
})
|
||||
_add_name(soundtrack, soundtrack)
|
||||
for alternative: String in alternatives.get(soundtrack, []):
|
||||
_add_name(soundtrack, alternative)
|
||||
|
||||
|
||||
## The alternative name of [param soundtrack_name] that matched in the last
|
||||
## [method find_matches], or an empty String when its real name matched.
|
||||
func matched_alternative(soundtrack_name: String) -> String:
|
||||
return _matched_alternatives.get(soundtrack_name, "")
|
||||
|
||||
|
||||
## Returns the names matching [param search_text], best matches first: plain
|
||||
@@ -41,11 +54,14 @@ func find_matches(search_text: String) -> Array[String]:
|
||||
func(entry: Dictionary) -> bool: return regex.search(entry.cleaned) != null)
|
||||
|
||||
var matches: Array[String] = []
|
||||
_matched_alternatives.clear()
|
||||
for matches_pass: Callable in passes:
|
||||
for entry: Dictionary in _names:
|
||||
if !seen.has(entry.original) && matches_pass.call(entry):
|
||||
seen[entry.original] = true
|
||||
matches.append(entry.original)
|
||||
if entry.text != entry.original:
|
||||
_matched_alternatives[entry.original] = entry.text
|
||||
return matches
|
||||
|
||||
|
||||
@@ -107,6 +123,15 @@ static func clean_term(term: String) -> String:
|
||||
.replace("'n", "and").to_lower()
|
||||
|
||||
|
||||
func _add_name(soundtrack: String, text: String) -> void:
|
||||
_names.append({
|
||||
"original": soundtrack,
|
||||
"text": text,
|
||||
"lowercase": text.to_lower(),
|
||||
"cleaned": clean_term(text),
|
||||
})
|
||||
|
||||
|
||||
# Compiles the letters-in-order pattern for [param search_term], once per term
|
||||
func _compile_regex_cached(search_term: String) -> RegEx:
|
||||
if not search_term in _regex_cache:
|
||||
|
||||
Reference in new issue
Block a user