|
2 | 2 | // See the LICENCE file in the repository root for full licence text. |
3 | 3 |
|
4 | 4 | using System; |
5 | | -using System.Collections.Generic; |
6 | 5 | using System.Linq; |
| 6 | +using System.Threading; |
| 7 | +using System.Threading.Tasks; |
7 | 8 | using osu.Framework.Allocation; |
8 | 9 | using osu.Framework.Bindables; |
| 10 | +using osu.Framework.Extensions; |
9 | 11 | using osu.Framework.Graphics; |
10 | 12 | using osu.Framework.Graphics.Containers; |
| 13 | +using osu.Framework.Logging; |
11 | 14 | using osu.Game.Beatmaps; |
| 15 | +using osu.Game.Database; |
12 | 16 | using osu.Game.Graphics.Containers; |
13 | 17 | using osu.Game.Localisation; |
14 | 18 | using osu.Game.Online; |
15 | 19 | using osu.Game.Online.API; |
16 | | -using osu.Game.Online.API.Requests; |
17 | 20 | using osu.Game.Online.API.Requests.Responses; |
18 | 21 | using osu.Game.Online.Chat; |
19 | 22 | using osu.Game.Resources.Localisation.Web; |
@@ -51,6 +54,12 @@ public partial class BeatmapMetadataWedge : VisibilityContainer |
51 | 54 | [Resolved] |
52 | 55 | private IAPIProvider api { get; set; } = null!; |
53 | 56 |
|
| 57 | + [Resolved] |
| 58 | + private RealmPopulatingOnlineLookupSource onlineLookupSource { get; set; } = null!; |
| 59 | + |
| 60 | + [Resolved] |
| 61 | + private RealmAccess realm { get; set; } = null!; |
| 62 | + |
54 | 63 | private IBindable<APIState> apiState = null!; |
55 | 64 |
|
56 | 65 | [Resolved] |
@@ -314,34 +323,34 @@ private void updateDisplay() |
314 | 323 | } |
315 | 324 |
|
316 | 325 | private APIBeatmapSet? currentOnlineBeatmapSet; |
317 | | - private GetBeatmapSetRequest? currentRequest; |
| 326 | + private CancellationTokenSource? cancellationTokenSource; |
| 327 | + private Task<APIBeatmapSet?>? currentFetchTask; |
318 | 328 |
|
319 | 329 | private void refetchBeatmapSet() |
320 | 330 | { |
321 | 331 | var beatmapSetInfo = beatmap.Value.BeatmapSetInfo; |
322 | 332 |
|
323 | | - currentRequest?.Cancel(); |
324 | | - currentRequest = null; |
| 333 | + cancellationTokenSource?.Cancel(); |
325 | 334 | currentOnlineBeatmapSet = null; |
326 | 335 |
|
327 | 336 | if (beatmapSetInfo.OnlineID >= 1) |
328 | 337 | { |
329 | | - // todo: consider introducing a BeatmapSetLookupCache for caching benefits. |
330 | | - currentRequest = new GetBeatmapSetRequest(beatmapSetInfo.OnlineID); |
331 | | - currentRequest.Failure += _ => updateOnlineDisplay(); |
332 | | - currentRequest.Success += s => |
| 338 | + cancellationTokenSource = new CancellationTokenSource(); |
| 339 | + currentFetchTask = onlineLookupSource.GetBeatmapSetAsync(beatmapSetInfo.OnlineID); |
| 340 | + currentFetchTask.ContinueWith(t => |
333 | 341 | { |
334 | | - currentOnlineBeatmapSet = s; |
335 | | - updateOnlineDisplay(); |
336 | | - }; |
337 | | - |
338 | | - api.Queue(currentRequest); |
| 342 | + if (t.IsCompletedSuccessfully) |
| 343 | + currentOnlineBeatmapSet = t.GetResultSafely(); |
| 344 | + if (t.Exception != null) |
| 345 | + Logger.Log($"Error when fetching online beatmap set: {t.Exception}", LoggingTarget.Network); |
| 346 | + Scheduler.AddOnce(updateOnlineDisplay); |
| 347 | + }); |
339 | 348 | } |
340 | 349 | } |
341 | 350 |
|
342 | 351 | private void updateOnlineDisplay() |
343 | 352 | { |
344 | | - if (currentRequest?.CompletionState == APIRequestCompletionState.Waiting) |
| 353 | + if (currentFetchTask?.IsCompleted == false) |
345 | 354 | { |
346 | 355 | genre.Data = null; |
347 | 356 | language.Data = null; |
@@ -379,28 +388,21 @@ private void updateOnlineDisplay() |
379 | 388 |
|
380 | 389 | private void updateUserTags() |
381 | 390 | { |
382 | | - var beatmapInfo = beatmap.Value.BeatmapInfo; |
383 | | - var onlineBeatmapSet = currentOnlineBeatmapSet; |
384 | | - var onlineBeatmap = onlineBeatmapSet?.Beatmaps.SingleOrDefault(b => b.OnlineID == beatmapInfo.OnlineID); |
| 391 | + string[] tags = realm.Run(r => |
| 392 | + { |
| 393 | + // need to refetch because `beatmap.Value.BeatmapInfo` is not going to have the latest tags |
| 394 | + var refetchedBeatmap = r.Find<BeatmapInfo>(beatmap.Value.BeatmapInfo.ID); |
| 395 | + return refetchedBeatmap?.Metadata.UserTags.ToArray() ?? []; |
| 396 | + }); |
385 | 397 |
|
386 | | - if (onlineBeatmap?.TopTags == null || onlineBeatmap.TopTags.Length == 0 || onlineBeatmapSet?.RelatedTags == null) |
| 398 | + if (tags.Length == 0) |
387 | 399 | { |
388 | 400 | userTags.FadeOut(transition_duration, Easing.OutQuint); |
389 | 401 | return; |
390 | 402 | } |
391 | 403 |
|
392 | | - var tagsById = onlineBeatmapSet.RelatedTags.ToDictionary(t => t.Id); |
393 | | - string[] userTagsArray = onlineBeatmap.TopTags |
394 | | - .Select(t => (topTag: t, relatedTag: tagsById.GetValueOrDefault(t.TagId))) |
395 | | - .Where(t => t.relatedTag != null) |
396 | | - // see https://github.com/ppy/osu-web/blob/bb3bd2e7c6f84f26066df5ea20a81c77ec9bb60a/resources/js/beatmapsets-show/controller.ts#L103-L106 for sort criteria |
397 | | - .OrderByDescending(t => t.topTag.VoteCount) |
398 | | - .ThenBy(t => t.relatedTag!.Name) |
399 | | - .Select(t => t.relatedTag!.Name) |
400 | | - .ToArray(); |
401 | | - |
402 | 404 | userTags.FadeIn(transition_duration, Easing.OutQuint); |
403 | | - userTags.Tags = (userTagsArray, t => songSelect?.Search(t)); |
| 405 | + userTags.Tags = (tags, t => songSelect?.Search($@"tag=""{t}""!")); |
404 | 406 | } |
405 | 407 | } |
406 | 408 | } |
0 commit comments