Remove CommentsPage component

This commit is contained in:
Andrei Zavatski
2020-02-26 17:38:50 +03:00
parent f1c97451d9
commit 56c41a614a
4 changed files with 112 additions and 418 deletions

View File

@ -9,10 +9,12 @@ using osu.Framework.Graphics;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Shapes;
using osu.Game.Online.API.Requests.Responses;
using System.Threading;
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Users;
using System.Collections.Generic;
using JetBrains.Annotations;
using osu.Game.Graphics.Sprites;
namespace osu.Game.Overlays.Comments
{
@ -30,7 +32,6 @@ namespace osu.Game.Overlays.Comments
private IAPIProvider api { get; set; }
private GetCommentsRequest request;
private CancellationTokenSource loadCancellation;
private int currentPage;
private FillFlowContainer content;
@ -151,9 +152,8 @@ namespace osu.Game.Overlays.Comments
return;
request?.Cancel();
loadCancellation?.Cancel();
request = new GetCommentsRequest(id.Value, type.Value, Sort.Value, currentPage++, 0);
request.Success += onSuccess;
request.Success += response => Schedule(() => onSuccess(response));
api.PerformAsync(request);
}
@ -166,44 +166,132 @@ namespace osu.Game.Overlays.Comments
content.Clear();
}
private readonly Dictionary<long, DrawableComment> commentDictionary = new Dictionary<long, DrawableComment>();
private void onSuccess(CommentBundle response)
{
loadCancellation = new CancellationTokenSource();
LoadComponentAsync(new CommentsPage(response)
if (!response.Comments.Any())
{
ShowDeleted = { BindTarget = ShowDeleted },
Sort = { BindTarget = Sort },
Type = { BindTarget = type },
CommentableId = { BindTarget = id }
}, loaded =>
content.Add(new NoCommentsPlaceholder());
return;
}
else
{
content.Add(loaded);
appendComments(response);
deletedCommentsCounter.Count.Value += response.Comments.Count(c => c.IsDeleted && c.IsTopLevel);
}
if (response.HasMore)
if (response.HasMore)
{
int loadedTopLevelComments = 0;
content.Children.OfType<DrawableComment>().ForEach(p => loadedTopLevelComments++);
moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments;
moreButton.IsLoading = false;
}
else
{
moreButton.Hide();
}
}
/// <summary>
/// Appends retrieved comments to the subtree rooted of comments in this page.
/// </summary>
/// <param name="bundle">The bundle of comments to add.</param>
private void appendComments([NotNull] CommentBundle bundle)
{
var orphaned = new List<Comment>();
foreach (var comment in bundle.Comments.Concat(bundle.IncludedComments))
{
// Exclude possible duplicated comments.
if (commentDictionary.ContainsKey(comment.Id))
continue;
addNewComment(comment);
}
// Comments whose parents were seen later than themselves can now be added.
foreach (var o in orphaned)
addNewComment(o);
void addNewComment(Comment comment)
{
var drawableComment = getDrawableComment(comment);
if (comment.ParentId == null)
{
int loadedTopLevelComments = 0;
content.Children.OfType<FillFlowContainer>().ForEach(p => loadedTopLevelComments += p.Children.OfType<DrawableComment>().Count());
moreButton.Current.Value = response.TopLevelCount - loadedTopLevelComments;
moreButton.IsLoading = false;
// Comments that have no parent are added as top-level comments to the flow.
content.Add(drawableComment);
}
else if (commentDictionary.TryGetValue(comment.ParentId.Value, out var parentDrawable))
{
// The comment's parent has already been seen, so the parent<-> child links can be added.
comment.ParentComment = parentDrawable.Comment;
parentDrawable.Replies.Add(drawableComment);
}
else
{
moreButton.Hide();
// The comment's parent has not been seen yet, so keep it orphaned for the time being. This can occur if the comments arrive out of order.
// Since this comment has now been seen, any further children can be added to it without being orphaned themselves.
orphaned.Add(comment);
}
}
}
commentCounter.Current.Value = response.Total;
}, loadCancellation.Token);
private DrawableComment getDrawableComment(Comment comment)
{
if (commentDictionary.TryGetValue(comment.Id, out var existing))
return existing;
return commentDictionary[comment.Id] = new DrawableComment(comment)
{
ShowDeleted = { BindTarget = ShowDeleted },
Sort = { BindTarget = Sort },
RepliesRequested = onCommentRepliesRequested
};
}
private void onCommentRepliesRequested(DrawableComment drawableComment, int page)
{
var request = new GetCommentsRequest(id.Value, type.Value, Sort.Value, page, drawableComment.Comment.Id);
request.Success += response => Schedule(() => appendComments(response));
api.PerformAsync(request);
}
protected override void Dispose(bool isDisposing)
{
request?.Cancel();
loadCancellation?.Cancel();
base.Dispose(isDisposing);
}
private class NoCommentsPlaceholder : CompositeDrawable
{
[BackgroundDependencyLoader]
private void load(OverlayColourProvider colourProvider)
{
Height = 80;
RelativeSizeAxes = Axes.X;
AddRangeInternal(new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4
},
new OsuSpriteText
{
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Margin = new MarginPadding { Left = 50 },
Text = @"No comments yet."
}
});
}
}
}
}