mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 03:22:55 +08:00
Merge pull request #20512 from Feodor0090/comment-deletion
Add ability to delete own comments
This commit is contained in:
commit
f573ee4521
257
osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
Normal file
257
osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Comments;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneCommentActions : OsuManualInputManagerTestScene
|
||||||
|
{
|
||||||
|
private Container<Drawable> content = null!;
|
||||||
|
protected override Container<Drawable> Content => content;
|
||||||
|
private DummyAPIAccess dummyAPI => (DummyAPIAccess)API;
|
||||||
|
|
||||||
|
[Cached(typeof(IDialogOverlay))]
|
||||||
|
private readonly DialogOverlay dialogOverlay = new DialogOverlay();
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||||
|
|
||||||
|
private CommentsContainer commentsContainer = null!;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
base.Content.AddRange(new Drawable[]
|
||||||
|
{
|
||||||
|
content = new OsuScrollContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both
|
||||||
|
},
|
||||||
|
dialogOverlay
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUp()
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
API.Login("test", "test");
|
||||||
|
Child = commentsContainer = new CommentsContainer();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNonOwnCommentCantBeDeleted()
|
||||||
|
{
|
||||||
|
addTestComments();
|
||||||
|
|
||||||
|
AddUntilStep("First comment has button", () =>
|
||||||
|
{
|
||||||
|
var comments = this.ChildrenOfType<DrawableComment>();
|
||||||
|
var ourComment = comments.SingleOrDefault(x => x.Comment.Id == 1);
|
||||||
|
return ourComment != null && ourComment.ChildrenOfType<OsuSpriteText>().Any(x => x.Text == "Delete");
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Second doesn't", () =>
|
||||||
|
{
|
||||||
|
var comments = this.ChildrenOfType<DrawableComment>();
|
||||||
|
var ourComment = comments.Single(x => x.Comment.Id == 2);
|
||||||
|
return ourComment.ChildrenOfType<OsuSpriteText>().All(x => x.Text != "Delete");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly ManualResetEventSlim deletionPerformed = new ManualResetEventSlim();
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDeletion()
|
||||||
|
{
|
||||||
|
DrawableComment? ourComment = null;
|
||||||
|
|
||||||
|
addTestComments();
|
||||||
|
AddUntilStep("Comment exists", () =>
|
||||||
|
{
|
||||||
|
var comments = this.ChildrenOfType<DrawableComment>();
|
||||||
|
ourComment = comments.SingleOrDefault(x => x.Comment.Id == 1);
|
||||||
|
return ourComment != null;
|
||||||
|
});
|
||||||
|
AddStep("It has delete button", () =>
|
||||||
|
{
|
||||||
|
var btn = ourComment.ChildrenOfType<OsuSpriteText>().Single(x => x.Text == "Delete");
|
||||||
|
InputManager.MoveMouseTo(btn);
|
||||||
|
});
|
||||||
|
AddStep("Click delete button", () =>
|
||||||
|
{
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddStep("Setup request handling", () =>
|
||||||
|
{
|
||||||
|
deletionPerformed.Reset();
|
||||||
|
|
||||||
|
dummyAPI.HandleRequest = request =>
|
||||||
|
{
|
||||||
|
if (!(request is CommentDeleteRequest req))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (req.CommentId != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
CommentBundle cb = new CommentBundle
|
||||||
|
{
|
||||||
|
Comments = new List<Comment>
|
||||||
|
{
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Message = "This is a comment by another user",
|
||||||
|
UserId = API.LocalUser.Value.Id + 1,
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
User = new APIUser
|
||||||
|
{
|
||||||
|
Id = API.LocalUser.Value.Id + 1,
|
||||||
|
Username = "Another user"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedComments = new List<Comment>(),
|
||||||
|
PinnedComments = new List<Comment>(),
|
||||||
|
};
|
||||||
|
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
deletionPerformed.Wait(10000);
|
||||||
|
req.TriggerSuccess(cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
AddStep("Confirm dialog", () => InputManager.Key(Key.Number1));
|
||||||
|
|
||||||
|
AddAssert("Loading spinner shown", () => commentsContainer.ChildrenOfType<LoadingSpinner>().Any(d => d.IsPresent));
|
||||||
|
|
||||||
|
AddStep("Complete request", () => deletionPerformed.Set());
|
||||||
|
|
||||||
|
AddUntilStep("Comment is deleted locally", () => this.ChildrenOfType<DrawableComment>().Single(x => x.Comment.Id == 1).WasDeleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDeletionFail()
|
||||||
|
{
|
||||||
|
DrawableComment? ourComment = null;
|
||||||
|
bool delete = false;
|
||||||
|
|
||||||
|
addTestComments();
|
||||||
|
AddUntilStep("Comment exists", () =>
|
||||||
|
{
|
||||||
|
var comments = this.ChildrenOfType<DrawableComment>();
|
||||||
|
ourComment = comments.SingleOrDefault(x => x.Comment.Id == 1);
|
||||||
|
return ourComment != null;
|
||||||
|
});
|
||||||
|
AddStep("It has delete button", () =>
|
||||||
|
{
|
||||||
|
var btn = ourComment.ChildrenOfType<OsuSpriteText>().Single(x => x.Text == "Delete");
|
||||||
|
InputManager.MoveMouseTo(btn);
|
||||||
|
});
|
||||||
|
AddStep("Click delete button", () =>
|
||||||
|
{
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
});
|
||||||
|
AddStep("Setup request handling", () =>
|
||||||
|
{
|
||||||
|
dummyAPI.HandleRequest = request =>
|
||||||
|
{
|
||||||
|
if (request is not CommentDeleteRequest req)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
req.TriggerFailure(new Exception());
|
||||||
|
delete = true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
AddStep("Confirm dialog", () => InputManager.Key(Key.Number1));
|
||||||
|
AddUntilStep("Deletion requested", () => delete);
|
||||||
|
AddUntilStep("Comment is available", () =>
|
||||||
|
{
|
||||||
|
return !this.ChildrenOfType<DrawableComment>().Single(x => x.Comment.Id == 1).WasDeleted;
|
||||||
|
});
|
||||||
|
AddAssert("Loading spinner hidden", () =>
|
||||||
|
{
|
||||||
|
return ourComment.ChildrenOfType<LoadingSpinner>().All(d => !d.IsPresent);
|
||||||
|
});
|
||||||
|
AddAssert("Actions available", () =>
|
||||||
|
{
|
||||||
|
return ourComment.ChildrenOfType<LinkFlowContainer>().Single(x => x.Name == @"Actions buttons").IsPresent;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTestComments()
|
||||||
|
{
|
||||||
|
AddStep("set up response", () =>
|
||||||
|
{
|
||||||
|
CommentBundle cb = new CommentBundle
|
||||||
|
{
|
||||||
|
Comments = new List<Comment>
|
||||||
|
{
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 1,
|
||||||
|
Message = "This is our comment",
|
||||||
|
UserId = API.LocalUser.Value.Id,
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
User = API.LocalUser.Value,
|
||||||
|
},
|
||||||
|
new Comment
|
||||||
|
{
|
||||||
|
Id = 2,
|
||||||
|
Message = "This is a comment by another user",
|
||||||
|
UserId = API.LocalUser.Value.Id + 1,
|
||||||
|
CreatedAt = DateTimeOffset.Now,
|
||||||
|
User = new APIUser
|
||||||
|
{
|
||||||
|
Id = API.LocalUser.Value.Id + 1,
|
||||||
|
Username = "Another user"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
IncludedComments = new List<Comment>(),
|
||||||
|
PinnedComments = new List<Comment>(),
|
||||||
|
};
|
||||||
|
setUpCommentsResponse(cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("show comments", () => commentsContainer.ShowComments(CommentableType.Beatmapset, 123));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpCommentsResponse(CommentBundle commentBundle)
|
||||||
|
{
|
||||||
|
dummyAPI.HandleRequest = request =>
|
||||||
|
{
|
||||||
|
if (!(request is GetCommentsRequest getCommentsRequest))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
getCommentsRequest.TriggerSuccess(commentBundle);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
osu.Game/Online/API/Requests/CommentDeleteRequest.cs
Normal file
28
osu.Game/Online/API/Requests/CommentDeleteRequest.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class CommentDeleteRequest : APIRequest<CommentBundle>
|
||||||
|
{
|
||||||
|
public readonly long CommentId;
|
||||||
|
|
||||||
|
public CommentDeleteRequest(long id)
|
||||||
|
{
|
||||||
|
CommentId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
req.Method = HttpMethod.Delete;
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => $@"comments/{CommentId}";
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
@ -16,18 +14,18 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"parent_id")]
|
[JsonProperty(@"parent_id")]
|
||||||
public long? ParentId { get; set; }
|
public long? ParentId { get; set; }
|
||||||
|
|
||||||
public Comment ParentComment { get; set; }
|
public Comment? ParentComment { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"user_id")]
|
[JsonProperty(@"user_id")]
|
||||||
public long? UserId { get; set; }
|
public long? UserId { get; set; }
|
||||||
|
|
||||||
public APIUser User { get; set; }
|
public APIUser? User { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"message")]
|
[JsonProperty(@"message")]
|
||||||
public string Message { get; set; }
|
public string Message { get; set; } = null!;
|
||||||
|
|
||||||
[JsonProperty(@"message_html")]
|
[JsonProperty(@"message_html")]
|
||||||
public string MessageHtml { get; set; }
|
public string? MessageHtml { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"replies_count")]
|
[JsonProperty(@"replies_count")]
|
||||||
public int RepliesCount { get; set; }
|
public int RepliesCount { get; set; }
|
||||||
@ -36,13 +34,13 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
public int VotesCount { get; set; }
|
public int VotesCount { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"commenatble_type")]
|
[JsonProperty(@"commenatble_type")]
|
||||||
public string CommentableType { get; set; }
|
public string CommentableType { get; set; } = null!;
|
||||||
|
|
||||||
[JsonProperty(@"commentable_id")]
|
[JsonProperty(@"commentable_id")]
|
||||||
public int CommentableId { get; set; }
|
public int CommentableId { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"legacy_name")]
|
[JsonProperty(@"legacy_name")]
|
||||||
public string LegacyName { get; set; }
|
public string? LegacyName { get; set; }
|
||||||
|
|
||||||
[JsonProperty(@"created_at")]
|
[JsonProperty(@"created_at")]
|
||||||
public DateTimeOffset CreatedAt { get; set; }
|
public DateTimeOffset CreatedAt { get; set; }
|
||||||
@ -62,7 +60,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
|||||||
[JsonProperty(@"pinned")]
|
[JsonProperty(@"pinned")]
|
||||||
public bool Pinned { get; set; }
|
public bool Pinned { get; set; }
|
||||||
|
|
||||||
public APIUser EditedUser { get; set; }
|
public APIUser? EditedUser { get; set; }
|
||||||
|
|
||||||
public bool IsTopLevel => !ParentId.HasValue;
|
public bool IsTopLevel => !ParentId.HasValue;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
@ -22,7 +20,11 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
using osu.Game.Overlays.Comments.Buttons;
|
using osu.Game.Overlays.Comments.Buttons;
|
||||||
|
using osu.Game.Overlays.Dialog;
|
||||||
using osu.Game.Resources.Localisation.Web;
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Comments
|
namespace osu.Game.Overlays.Comments
|
||||||
@ -31,7 +33,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
{
|
{
|
||||||
private const int avatar_size = 40;
|
private const int avatar_size = 40;
|
||||||
|
|
||||||
public Action<DrawableComment, int> RepliesRequested;
|
public Action<DrawableComment, int> RepliesRequested = null!;
|
||||||
|
|
||||||
public readonly Comment Comment;
|
public readonly Comment Comment;
|
||||||
|
|
||||||
@ -45,13 +47,29 @@ namespace osu.Game.Overlays.Comments
|
|||||||
|
|
||||||
private int currentPage;
|
private int currentPage;
|
||||||
|
|
||||||
private FillFlowContainer childCommentsVisibilityContainer;
|
/// <summary>
|
||||||
private FillFlowContainer childCommentsContainer;
|
/// Local field for tracking comment state. Initialized from Comment.IsDeleted, may change when deleting was requested by user.
|
||||||
private LoadRepliesButton loadRepliesButton;
|
/// </summary>
|
||||||
private ShowMoreRepliesButton showMoreButton;
|
public bool WasDeleted { get; protected set; }
|
||||||
private ShowRepliesButton showRepliesButton;
|
|
||||||
private ChevronButton chevronButton;
|
private FillFlowContainer childCommentsVisibilityContainer = null!;
|
||||||
private DeletedCommentsCounter deletedCommentsCounter;
|
private FillFlowContainer childCommentsContainer = null!;
|
||||||
|
private LoadRepliesButton loadRepliesButton = null!;
|
||||||
|
private ShowMoreRepliesButton showMoreButton = null!;
|
||||||
|
private ShowRepliesButton showRepliesButton = null!;
|
||||||
|
private ChevronButton chevronButton = null!;
|
||||||
|
private LinkFlowContainer actionsContainer = null!;
|
||||||
|
private LoadingSpinner actionsLoading = null!;
|
||||||
|
private DeletedCommentsCounter deletedCommentsCounter = null!;
|
||||||
|
private OsuSpriteText deletedLabel = null!;
|
||||||
|
private GridContainer content = null!;
|
||||||
|
private VotePill votePill = null!;
|
||||||
|
|
||||||
|
[Resolved(canBeNull: true)]
|
||||||
|
private IDialogOverlay? dialogOverlay { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IAPIProvider api { get; set; } = null!;
|
||||||
|
|
||||||
public DrawableComment(Comment comment)
|
public DrawableComment(Comment comment)
|
||||||
{
|
{
|
||||||
@ -64,8 +82,6 @@ namespace osu.Game.Overlays.Comments
|
|||||||
LinkFlowContainer username;
|
LinkFlowContainer username;
|
||||||
FillFlowContainer info;
|
FillFlowContainer info;
|
||||||
CommentMarkdownContainer message;
|
CommentMarkdownContainer message;
|
||||||
GridContainer content;
|
|
||||||
VotePill votePill;
|
|
||||||
|
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
@ -148,9 +164,9 @@ namespace osu.Game.Overlays.Comments
|
|||||||
},
|
},
|
||||||
Comment.Pinned ? new PinnedCommentNotice() : Empty(),
|
Comment.Pinned ? new PinnedCommentNotice() : Empty(),
|
||||||
new ParentUsername(Comment),
|
new ParentUsername(Comment),
|
||||||
new OsuSpriteText
|
deletedLabel = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Alpha = Comment.IsDeleted ? 1 : 0,
|
Alpha = 0f,
|
||||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold),
|
||||||
Text = CommentsStrings.Deleted
|
Text = CommentsStrings.Deleted
|
||||||
}
|
}
|
||||||
@ -163,6 +179,13 @@ namespace osu.Game.Overlays.Comments
|
|||||||
DocumentMargin = new MarginPadding(0),
|
DocumentMargin = new MarginPadding(0),
|
||||||
DocumentPadding = new MarginPadding(0),
|
DocumentPadding = new MarginPadding(0),
|
||||||
},
|
},
|
||||||
|
new FillFlowContainer
|
||||||
|
{
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Direction = FillDirection.Horizontal,
|
||||||
|
Spacing = new Vector2(10, 0),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
info = new FillFlowContainer
|
info = new FillFlowContainer
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
@ -176,6 +199,20 @@ namespace osu.Game.Overlays.Comments
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
actionsContainer = new LinkFlowContainer(s => s.Font = OsuFont.GetFont(size: 12, weight: FontWeight.Bold))
|
||||||
|
{
|
||||||
|
Name = @"Actions buttons",
|
||||||
|
AutoSizeAxes = Axes.Both,
|
||||||
|
Spacing = new Vector2(10, 0)
|
||||||
|
},
|
||||||
|
actionsLoading = new LoadingSpinner
|
||||||
|
{
|
||||||
|
Size = new Vector2(12f),
|
||||||
|
Anchor = Anchor.TopLeft,
|
||||||
|
Origin = Anchor.TopLeft
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
AutoSizeAxes = Axes.Both,
|
AutoSizeAxes = Axes.Both,
|
||||||
@ -246,9 +283,9 @@ namespace osu.Game.Overlays.Comments
|
|||||||
if (Comment.UserId.HasValue)
|
if (Comment.UserId.HasValue)
|
||||||
username.AddUserLink(Comment.User);
|
username.AddUserLink(Comment.User);
|
||||||
else
|
else
|
||||||
username.AddText(Comment.LegacyName);
|
username.AddText(Comment.LegacyName!);
|
||||||
|
|
||||||
if (Comment.EditedAt.HasValue)
|
if (Comment.EditedAt.HasValue && Comment.EditedUser != null)
|
||||||
{
|
{
|
||||||
var font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular);
|
var font = OsuFont.GetFont(size: 12, weight: FontWeight.Regular);
|
||||||
var colour = colourProvider.Foreground1;
|
var colour = colourProvider.Foreground1;
|
||||||
@ -282,10 +319,13 @@ namespace osu.Game.Overlays.Comments
|
|||||||
if (Comment.HasMessage)
|
if (Comment.HasMessage)
|
||||||
message.Text = Comment.Message;
|
message.Text = Comment.Message;
|
||||||
|
|
||||||
if (Comment.IsDeleted)
|
WasDeleted = Comment.IsDeleted;
|
||||||
|
if (WasDeleted)
|
||||||
|
makeDeleted();
|
||||||
|
|
||||||
|
if (Comment.UserId.HasValue && Comment.UserId.Value == api.LocalUser.Value.Id)
|
||||||
{
|
{
|
||||||
content.FadeColour(OsuColour.Gray(0.5f));
|
actionsContainer.AddLink("Delete", deleteComment);
|
||||||
votePill.Hide();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Comment.IsTopLevel)
|
if (Comment.IsTopLevel)
|
||||||
@ -317,11 +357,57 @@ namespace osu.Game.Overlays.Comments
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transforms some comment's components to show it as deleted. Invoked both from loading and deleting.
|
||||||
|
/// </summary>
|
||||||
|
private void makeDeleted()
|
||||||
|
{
|
||||||
|
deletedLabel.Show();
|
||||||
|
content.FadeColour(OsuColour.Gray(0.5f));
|
||||||
|
votePill.Hide();
|
||||||
|
actionsContainer.Expire();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes comment deletion with confirmation.
|
||||||
|
/// </summary>
|
||||||
|
private void deleteComment()
|
||||||
|
{
|
||||||
|
if (dialogOverlay == null)
|
||||||
|
deleteCommentRequest();
|
||||||
|
else
|
||||||
|
dialogOverlay.Push(new ConfirmDialog("Do you really want to delete your comment?", deleteCommentRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes comment deletion directly.
|
||||||
|
/// </summary>
|
||||||
|
private void deleteCommentRequest()
|
||||||
|
{
|
||||||
|
actionsContainer.Hide();
|
||||||
|
actionsLoading.Show();
|
||||||
|
var request = new CommentDeleteRequest(Comment.Id);
|
||||||
|
request.Success += _ => Schedule(() =>
|
||||||
|
{
|
||||||
|
actionsLoading.Hide();
|
||||||
|
makeDeleted();
|
||||||
|
WasDeleted = true;
|
||||||
|
if (!ShowDeleted.Value)
|
||||||
|
Hide();
|
||||||
|
});
|
||||||
|
request.Failure += _ => Schedule(() =>
|
||||||
|
{
|
||||||
|
actionsLoading.Hide();
|
||||||
|
actionsContainer.Show();
|
||||||
|
});
|
||||||
|
api.Queue(request);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
ShowDeleted.BindValueChanged(show =>
|
ShowDeleted.BindValueChanged(show =>
|
||||||
{
|
{
|
||||||
if (Comment.IsDeleted)
|
if (WasDeleted)
|
||||||
this.FadeTo(show.NewValue ? 1 : 0);
|
this.FadeTo(show.NewValue ? 1 : 0);
|
||||||
}, true);
|
}, true);
|
||||||
childrenExpanded.BindValueChanged(expanded => childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0), true);
|
childrenExpanded.BindValueChanged(expanded => childCommentsVisibilityContainer.FadeTo(expanded.NewValue ? 1 : 0), true);
|
||||||
@ -425,7 +511,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
{
|
{
|
||||||
public LocalisableString TooltipText => getParentMessage();
|
public LocalisableString TooltipText => getParentMessage();
|
||||||
|
|
||||||
private readonly Comment parentComment;
|
private readonly Comment? parentComment;
|
||||||
|
|
||||||
public ParentUsername(Comment comment)
|
public ParentUsername(Comment comment)
|
||||||
{
|
{
|
||||||
@ -445,7 +531,7 @@ namespace osu.Game.Overlays.Comments
|
|||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.Bold, italics: true),
|
||||||
Text = parentComment?.User?.Username ?? parentComment?.LegacyName
|
Text = parentComment?.User?.Username ?? parentComment?.LegacyName!
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user