Takes changes in https://github.com/ppy/osu/pull/34233 and removes *all*
of the complexity.
Supersedes and closes#34233.
Contains same caveat that we can only display one beatmap once in the
carousel; this will be addressed separately.
Closes https://github.com/ppy/osu/issues/34445.
The primary issue is that song select is the only one that supports
non-score sort mode, and therefore if any other component changes the
sort mode in a way opaque to song select to score, then song select will
lose the sort mode because it's using the global leaderboard manager's
state which will contain scores sorted by total.
Notably, the bug this is fixing requires specific circumstances. For
instance, it is not enough to just *start gameplay* for the bug to
manifest, because starting gameplay causes a working beatmap refetch:
https://github.com/ppy/osu/blob/4b73afd1957a9161e2956fc4191c8114d9958372/osu.Game/Screens/SelectV2/SongSelect.cs#L456-L457
which will trigger a *delayed schedule refetch* of the scores:
https://github.com/ppy/osu/blob/d2d3d14f1572ff8fc68fd01ea43c2ef68b5882fa/osu.Game/Screens/SelectV2/BeatmapLeaderboardWedge.cs#L235-L253
and because the refetch is thusly delayed, there's a very high chance it
*will not run before the screen is resumed* because the wedge will not
have its scheduler run until that point in time.
This conundrum is also because there is no test coverage for this,
because the above makes test coverage setup rather annoying.
The way that this works is that it plugs into the online request to
retrieve the beatmap set that the client is already performing, and
stores user tag data to the local realm database.
This means that for now user tags will only populate for beatmaps that
the user has displayed on song select which is obviously subpar. I plan
to follow this change up by adding user tag state dumps to `online.db`
and using that data for initial tag population to make the majority case
(ranked beatmaps) work.
Note that several decisions were made here that are potential discussion
points:
- `RealmPopulatingOnlineLookupSource` is set up such that it can be the
middle man / redirection point for similar flows that we need and we
are currently missing, such as storing guest difficulty information,
or storing the user's current best score on a beatmap (handy for rank
achieved sorting / filtering / etc.)
- The user tags are stored in `BeatmapMetadata` which breaks the
longstanding assumption that you can arbitrarily pull out a metadata
instance from any of the beatmaps in a set and get essentially the
same object back.
I've attempted to constrain this some by not adding user tags to
the `IBeatmapMetadataInfo` interface through which `BeatmapSetInfo`
exposes metadata further, but I warn in advance that this is
a temporary state of affairs and I will make it worse in the future
when `BeatmapMetadata.Author` becomes `Authors` plural in order to
support guest mapper display (and direct guest difficulty submission).
- The syntax for searching via user tags is chosen to mostly match web -
it's `tag=`, with support for all of the string matching modes song
select already has (bare word for substring, `""` quotes for phrase
isolated by whitespace, `""!` for exact full match).
This is being run in the flow where we are providing a specific beatmap
for immediately selection. In an edge case scenario, the carousel may be
pending on a filter operation, which would cause the whole `SelectAndRun`
call to fail when it doesn't need to.
This is reproduced by multiple test scenes. One example is
`TestSceneOpenEditorTimestamp.TestErrorNotifications`.
Noticed in a flaky test with the changes to random, where the debounce
may be delayed to the point of thinking the selection is invalid even
though it's valid (timing woes, I cannot explain in words but I would
highly recommend smiling and nodding approach).
This was causing the logo to not be clickable immediately after closing
the overlay, which was reported as frustrating by some user.
I hoped to fix this by unfuckulating the logo logic but it's a multi-day
excursion that I'd rather avoid for now.
Before attempting to fix issues with invalid selections reaching
gameplay, I needed to do a pass of the song select class as selection
logic was already more complex than I'd hope.
All operations now go through a single flow (`SelectAndRun`) when
leaving the song select screen in a "success" state.