Add async loading support

This commit is contained in:
Andrei Zavatski 2020-02-26 18:00:48 +03:00
parent 56c41a614a
commit ae4f5cdf37

View File

@ -9,6 +9,7 @@ using osu.Framework.Graphics;
using osu.Framework.Bindables; using osu.Framework.Bindables;
using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Shapes;
using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.API.Requests.Responses;
using System.Threading;
using System.Linq; using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Users; using osu.Game.Users;
@ -32,6 +33,7 @@ namespace osu.Game.Overlays.Comments
private IAPIProvider api { get; set; } private IAPIProvider api { get; set; }
private GetCommentsRequest request; private GetCommentsRequest request;
private CancellationTokenSource loadCancellation;
private int currentPage; private int currentPage;
private FillFlowContainer content; private FillFlowContainer content;
@ -152,6 +154,7 @@ namespace osu.Game.Overlays.Comments
return; return;
request?.Cancel(); request?.Cancel();
loadCancellation?.Cancel();
request = new GetCommentsRequest(id.Value, type.Value, Sort.Value, currentPage++, 0); request = new GetCommentsRequest(id.Value, type.Value, Sort.Value, currentPage++, 0);
request.Success += response => Schedule(() => onSuccess(response)); request.Success += response => Schedule(() => onSuccess(response));
api.PerformAsync(request); api.PerformAsync(request);
@ -164,6 +167,7 @@ namespace osu.Game.Overlays.Comments
moreButton.Show(); moreButton.Show();
moreButton.IsLoading = true; moreButton.IsLoading = true;
content.Clear(); content.Clear();
commentDictionary.Clear();
} }
private readonly Dictionary<long, DrawableComment> commentDictionary = new Dictionary<long, DrawableComment>(); private readonly Dictionary<long, DrawableComment> commentDictionary = new Dictionary<long, DrawableComment>();
@ -173,26 +177,33 @@ namespace osu.Game.Overlays.Comments
if (!response.Comments.Any()) if (!response.Comments.Any())
{ {
content.Add(new NoCommentsPlaceholder()); content.Add(new NoCommentsPlaceholder());
moreButton.Hide();
return; return;
} }
else else
{ {
appendComments(response); var topLevelComments = appendComments(response);
deletedCommentsCounter.Count.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel); LoadComponentsAsync(topLevelComments, loaded =>
} {
content.AddRange(loaded);
if (response.HasMore) deletedCommentsCounter.Count.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel);
{ commentCounter.Current.Value = response.Total;
int loadedTopLevelComments = 0;
content.Children.OfType<DrawableComment>().ForEach(p => loadedTopLevelComments++);
moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments; if (response.HasMore)
moreButton.IsLoading = false; {
} int loadedTopLevelComments = 0;
else content.Children.OfType<DrawableComment>().ForEach(p => loadedTopLevelComments++);
{
moreButton.Hide(); moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments;
moreButton.IsLoading = false;
}
else
{
moreButton.Hide();
}
}, (loadCancellation = new CancellationTokenSource()).Token);
} }
} }
@ -200,8 +211,9 @@ namespace osu.Game.Overlays.Comments
/// Appends retrieved comments to the subtree rooted of comments in this page. /// Appends retrieved comments to the subtree rooted of comments in this page.
/// </summary> /// </summary>
/// <param name="bundle">The bundle of comments to add.</param> /// <param name="bundle">The bundle of comments to add.</param>
private void appendComments([NotNull] CommentBundle bundle) private List<DrawableComment> appendComments([NotNull] CommentBundle bundle)
{ {
var topLevelComments = new List<DrawableComment>();
var orphaned = new List<Comment>(); var orphaned = new List<Comment>();
foreach (var comment in bundle.Comments.Concat(bundle.IncludedComments)) foreach (var comment in bundle.Comments.Concat(bundle.IncludedComments))
@ -217,6 +229,8 @@ namespace osu.Game.Overlays.Comments
foreach (var o in orphaned) foreach (var o in orphaned)
addNewComment(o); addNewComment(o);
return topLevelComments;
void addNewComment(Comment comment) void addNewComment(Comment comment)
{ {
var drawableComment = getDrawableComment(comment); var drawableComment = getDrawableComment(comment);
@ -224,7 +238,7 @@ namespace osu.Game.Overlays.Comments
if (comment.ParentId == null) if (comment.ParentId == null)
{ {
// Comments that have no parent are added as top-level comments to the flow. // Comments that have no parent are added as top-level comments to the flow.
content.Add(drawableComment); topLevelComments.Add(drawableComment);
} }
else if (commentDictionary.TryGetValue(comment.ParentId.Value, out var parentDrawable)) else if (commentDictionary.TryGetValue(comment.ParentId.Value, out var parentDrawable))
{ {
@ -266,6 +280,7 @@ namespace osu.Game.Overlays.Comments
protected override void Dispose(bool isDisposing) protected override void Dispose(bool isDisposing)
{ {
request?.Cancel(); request?.Cancel();
loadCancellation?.Cancel();
base.Dispose(isDisposing); base.Dispose(isDisposing);
} }