osu/osu.Game/Tests/PollingChatClient.cs
Bartłomiej Dach de52f0a80c
Decouple notifications websocket handling from chat operations
This is a prerequisite for https://github.com/ppy/osu/pull/25480.

The `WebSocketNotificationsClient` was tightly coupled to chat specifics
making it difficult to use in the second factor verification flow.
This commit's goal is to separate the websocket connection and message
handling concerns from specific chat logic concerns.
2024-01-25 14:47:29 +01:00

83 lines
2.4 KiB
C#

// 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 osu.Game.Online;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.Chat;
namespace osu.Game.Tests
{
public class PollingChatClient : PersistentEndpointClient
{
public event Action<Channel>? ChannelJoined;
public event Action<List<Message>>? NewMessages;
public event Action? PresenceReceived;
private readonly IAPIProvider api;
private long lastMessageId;
public PollingChatClient(IAPIProvider api)
{
this.api = api;
}
public override Task ConnectAsync(CancellationToken cancellationToken)
{
Task.Run(async () =>
{
while (!cancellationToken.IsCancellationRequested)
{
await api.PerformAsync(CreateInitialFetchRequest()).ConfigureAwait(true);
await Task.Delay(1000, cancellationToken).ConfigureAwait(true);
}
}, cancellationToken);
return Task.CompletedTask;
}
protected APIRequest CreateInitialFetchRequest(long? lastMessageId = null)
{
var fetchReq = new GetUpdatesRequest(lastMessageId ?? this.lastMessageId);
fetchReq.Success += updates =>
{
if (updates?.Presence != null)
{
foreach (var channel in updates.Presence)
handleChannelJoined(channel);
//todo: handle left channels
handleMessages(updates.Messages);
}
PresenceReceived?.Invoke();
};
return fetchReq;
}
private void handleChannelJoined(Channel channel)
{
channel.Joined.Value = true;
ChannelJoined?.Invoke(channel);
}
private void handleMessages(List<Message>? messages)
{
if (messages == null)
return;
NewMessages?.Invoke(messages);
lastMessageId = Math.Max(lastMessageId, messages.LastOrDefault()?.Id ?? 0);
}
}
}