1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 12:33:01 +08:00

Remove messages from silenced users

This commit is contained in:
Dan Balasescu 2022-11-02 17:13:14 +09:00
parent f688ed12d0
commit 063a8bdf9e
4 changed files with 68 additions and 3 deletions

View File

@ -23,6 +23,7 @@ namespace osu.Game.Tests.Chat
private ChannelManager channelManager;
private int currentMessageId;
private List<Message> sentMessages;
private List<int> silencedUserIds;
[SetUp]
public void Setup() => Schedule(() =>
@ -39,6 +40,7 @@ namespace osu.Game.Tests.Chat
{
currentMessageId = 0;
sentMessages = new List<Message>();
silencedUserIds = new List<int>();
((DummyAPIAccess)API).HandleRequest = req =>
{
@ -55,6 +57,11 @@ namespace osu.Game.Tests.Chat
case MarkChannelAsReadRequest markRead:
handleMarkChannelAsReadRequest(markRead);
return true;
case ChatAckRequest ack:
ack.TriggerSuccess(new ChatAckResponse { Silences = silencedUserIds.Select(u => new ChatSilence { UserId = u }).ToList() });
silencedUserIds.Clear();
return true;
}
return false;
@ -106,6 +113,28 @@ namespace osu.Game.Tests.Chat
AddAssert("channel's last read ID is set to the latest message", () => channel.LastReadId == sentMessages.Last().Id);
}
[Test]
public void TestSilencedUsersAreRemoved()
{
Channel channel = null;
AddStep("join channel and select it", () =>
{
channelManager.JoinChannel(channel = createChannel(1, ChannelType.Public));
channelManager.CurrentChannel.Value = channel;
});
AddStep("post message", () => channelManager.PostMessage("Definitely something bad"));
AddStep("mark user as silenced and send ack request", () =>
{
silencedUserIds.Add(API.LocalUser.Value.OnlineID);
channelManager.SendAck();
});
AddAssert("channel has no more messages", () => channel.Messages, () => Is.Empty);
}
private void handlePostMessageRequest(PostMessageRequest request)
{
var message = new Message(++currentMessageId)

View File

@ -9,10 +9,16 @@ namespace osu.Game.Online.API.Requests
{
public class ChatAckRequest : APIRequest<ChatAckResponse>
{
public long SinceMessageId;
public uint? SinceSilenceId;
protected override WebRequest CreateWebRequest()
{
var req = base.CreateWebRequest();
req.Method = HttpMethod.Post;
req.AddParameter(@"since", SinceMessageId.ToString());
if (SinceSilenceId != null)
req.AddParameter(@"history_since", SinceSilenceId.Value.ToString());
return req;
}

View File

@ -12,6 +12,6 @@ namespace osu.Game.Online.API.Requests.Responses
public uint Id { get; set; }
[JsonProperty("user_id")]
public uint UserId { get; set; }
public int UserId { get; set; }
}
}

View File

@ -74,6 +74,9 @@ namespace osu.Game.Online.Chat
private bool channelsInitialised;
private ScheduledDelegate ackDelegate;
private long lastMessageId;
private uint? lastSilenceId;
public ChannelManager(IAPIProvider api, NotificationsClientConnector connector)
{
this.api = api;
@ -106,8 +109,7 @@ namespace osu.Game.Online.Chat
if (status.NewValue == APIState.Online)
{
Scheduler.Add(ackDelegate = new ScheduledDelegate(() => api.Queue(new ChatAckRequest()), 0, 60000));
// Todo: Handle silences.
Scheduler.Add(ackDelegate = new ScheduledDelegate(SendAck, 0, 60000));
}
}, true);
}
@ -342,6 +344,8 @@ namespace osu.Game.Online.Chat
foreach (var group in messages.GroupBy(m => m.ChannelId))
channels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
lastMessageId = messages.LastOrDefault()?.Id ?? lastMessageId;
}
private void initializeChannels()
@ -391,6 +395,32 @@ namespace osu.Game.Online.Chat
api.Queue(fetchInitialMsgReq);
}
/// <summary>
/// Sends an acknowledgement request to the API.
/// This marks the user as online to receive messages from public channels, while also returning a list of silenced users.
/// It needs to be called at least once every 10 minutes.
/// </summary>
public void SendAck()
{
var req = new ChatAckRequest
{
SinceMessageId = lastMessageId,
SinceSilenceId = lastSilenceId
};
req.Success += ack =>
{
foreach (var silence in ack.Silences)
{
foreach (var channel in JoinedChannels)
channel.RemoveMessagesFromUser(silence.UserId);
lastSilenceId = Math.Max(lastSilenceId ?? 0, silence.Id);
}
};
api.Queue(req);
}
/// <summary>
/// Find an existing channel instance for the provided channel. Lookup is performed basd on ID.
/// The provided channel may be used if an existing instance is not found.