mirror of
https://github.com/ppy/osu.git
synced 2025-02-22 00:43:25 +08:00
Add support for creating new PM conversations
This commit is contained in:
parent
82ebc74eee
commit
72ae22b0c4
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
|
using osu.Framework.IO.Network;
|
||||||
|
using osu.Game.Online.Chat;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class CreateNewPrivateMessageRequest : APIRequest<CreateNewPrivateMessageResponse>
|
||||||
|
{
|
||||||
|
private readonly User user;
|
||||||
|
private readonly Message message;
|
||||||
|
|
||||||
|
public CreateNewPrivateMessageRequest(User user, Message message)
|
||||||
|
{
|
||||||
|
this.user = user;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
req.Method = HttpMethod.Post;
|
||||||
|
req.AddParameter(@"target_id", user.Id.ToString());
|
||||||
|
req.AddParameter(@"message", message.Content);
|
||||||
|
req.AddParameter(@"is_action", message.IsAction.ToString().ToLowerInvariant());
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override string Target => @"chat/new";
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||||
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Online.Chat;
|
||||||
|
|
||||||
|
namespace osu.Game.Online.API.Requests
|
||||||
|
{
|
||||||
|
public class CreateNewPrivateMessageResponse
|
||||||
|
{
|
||||||
|
[JsonProperty("new_channel_id")]
|
||||||
|
public int ChannelID;
|
||||||
|
|
||||||
|
public Message Message;
|
||||||
|
}
|
||||||
|
}
|
@ -100,7 +100,7 @@ namespace osu.Game.Online.Chat
|
|||||||
NewMessagesArrived?.Invoke(new[] { message });
|
NewMessagesArrived?.Invoke(new[] { message });
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MessagesLoaded { get; private set; }
|
public bool MessagesLoaded;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds new messages to the channel and purges old messages. Triggers the <see cref="NewMessagesArrived"/> event.
|
/// Adds new messages to the channel and purges old messages. Triggers the <see cref="NewMessagesArrived"/> event.
|
||||||
@ -113,7 +113,6 @@ namespace osu.Game.Online.Chat
|
|||||||
if (messages.Length == 0) return;
|
if (messages.Length == 0) return;
|
||||||
|
|
||||||
Messages.AddRange(messages);
|
Messages.AddRange(messages);
|
||||||
MessagesLoaded = true;
|
|
||||||
|
|
||||||
var maxMessageId = messages.Max(m => m.Id);
|
var maxMessageId = messages.Max(m => m.Id);
|
||||||
if (maxMessageId > LastMessageId)
|
if (maxMessageId > LastMessageId)
|
||||||
|
@ -88,6 +88,12 @@ namespace osu.Game.Online.Chat
|
|||||||
JoinChannel(channel);
|
JoinChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensure we run post actions in sequence, once at a time.
|
||||||
|
/// </summary>
|
||||||
|
private readonly Queue<Action> postQueue = new Queue<Action>();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Posts a message to the currently opened channel.
|
/// Posts a message to the currently opened channel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -100,31 +106,70 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
var currentChannel = CurrentChannel.Value;
|
var currentChannel = CurrentChannel.Value;
|
||||||
|
|
||||||
if (!api.IsLoggedIn)
|
void dequeueAndRun()
|
||||||
{
|
{
|
||||||
currentChannel.AddNewMessages(new ErrorMessage("Please sign in to participate in chat!"));
|
if (postQueue.Count > 0)
|
||||||
return;
|
postQueue.Dequeue().Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
var message = new LocalEchoMessage
|
postQueue.Enqueue(() =>
|
||||||
{
|
{
|
||||||
Sender = api.LocalUser.Value,
|
if (!api.IsLoggedIn)
|
||||||
Timestamp = DateTimeOffset.Now,
|
{
|
||||||
ChannelId = CurrentChannel.Value.Id,
|
currentChannel.AddNewMessages(new ErrorMessage("Please sign in to participate in chat!"));
|
||||||
IsAction = isAction,
|
return;
|
||||||
Content = text
|
}
|
||||||
};
|
|
||||||
|
|
||||||
currentChannel.AddLocalEcho(message);
|
var message = new LocalEchoMessage
|
||||||
|
{
|
||||||
|
Sender = api.LocalUser.Value,
|
||||||
|
Timestamp = DateTimeOffset.Now,
|
||||||
|
ChannelId = CurrentChannel.Value.Id,
|
||||||
|
IsAction = isAction,
|
||||||
|
Content = text
|
||||||
|
};
|
||||||
|
|
||||||
var req = new PostMessageRequest(message);
|
currentChannel.AddLocalEcho(message);
|
||||||
req.Failure += exception =>
|
|
||||||
{
|
// if this is a PM and the first message, we need to do a special request to create the PM channel
|
||||||
Logger.Error(exception, "Posting message failed.");
|
if (currentChannel.Type == ChannelType.PM && !currentChannel.Joined)
|
||||||
currentChannel.ReplaceMessage(message, null);
|
{
|
||||||
};
|
var createNewPrivateMessageRequest = new CreateNewPrivateMessageRequest(currentChannel.Users.First(), message);
|
||||||
req.Success += m => currentChannel.ReplaceMessage(message, m);
|
createNewPrivateMessageRequest.Success += createRes =>
|
||||||
api.Queue(req);
|
{
|
||||||
|
currentChannel.Id = createRes.ChannelID;
|
||||||
|
currentChannel.ReplaceMessage(message, createRes.Message);
|
||||||
|
dequeueAndRun();
|
||||||
|
};
|
||||||
|
createNewPrivateMessageRequest.Failure += exception =>
|
||||||
|
{
|
||||||
|
Logger.Error(exception, "Posting message failed.");
|
||||||
|
currentChannel.ReplaceMessage(message, null);
|
||||||
|
dequeueAndRun();
|
||||||
|
};
|
||||||
|
|
||||||
|
api.Queue(createNewPrivateMessageRequest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var req = new PostMessageRequest(message);
|
||||||
|
req.Success += m =>
|
||||||
|
{
|
||||||
|
currentChannel.ReplaceMessage(message, m);
|
||||||
|
dequeueAndRun();
|
||||||
|
};
|
||||||
|
req.Failure += exception =>
|
||||||
|
{
|
||||||
|
Logger.Error(exception, "Posting message failed.");
|
||||||
|
currentChannel.ReplaceMessage(message, null);
|
||||||
|
dequeueAndRun();
|
||||||
|
};
|
||||||
|
api.Queue(req);
|
||||||
|
});
|
||||||
|
|
||||||
|
// always run if the queue is empty
|
||||||
|
if (postQueue.Count == 1)
|
||||||
|
dequeueAndRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -170,11 +215,11 @@ namespace osu.Game.Online.Chat
|
|||||||
channels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
|
channels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeDefaultChannels()
|
private void initializeChannels()
|
||||||
{
|
{
|
||||||
var req = new ListChannelsRequest();
|
var req = new ListChannelsRequest();
|
||||||
|
|
||||||
//var joinDefaults = JoinedChannels.Count == 0;
|
var joinDefaults = JoinedChannels.Count == 0;
|
||||||
|
|
||||||
req.Success += channels =>
|
req.Success += channels =>
|
||||||
{
|
{
|
||||||
@ -185,14 +230,14 @@ namespace osu.Game.Online.Chat
|
|||||||
AvailableChannels.Add(channel);
|
AvailableChannels.Add(channel);
|
||||||
|
|
||||||
// join any channels classified as "defaults"
|
// join any channels classified as "defaults"
|
||||||
/*if (joinDefaults && defaultChannels.Any(c => c.Equals(channel.Name, StringComparison.OrdinalIgnoreCase)))
|
if (joinDefaults && defaultChannels.Any(c => c.Equals(channel.Name, StringComparison.OrdinalIgnoreCase)))
|
||||||
JoinChannel(channel);*/
|
JoinChannel(channel);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
req.Failure += error =>
|
req.Failure += error =>
|
||||||
{
|
{
|
||||||
Logger.Error(error, "Fetching channel list failed");
|
Logger.Error(error, "Fetching channel list failed");
|
||||||
initializeDefaultChannels();
|
initializeChannels();
|
||||||
};
|
};
|
||||||
|
|
||||||
api.Queue(req);
|
api.Queue(req);
|
||||||
@ -207,9 +252,15 @@ namespace osu.Game.Online.Chat
|
|||||||
/// <param name="channel">The channel </param>
|
/// <param name="channel">The channel </param>
|
||||||
private void fetchInitalMessages(Channel channel)
|
private void fetchInitalMessages(Channel channel)
|
||||||
{
|
{
|
||||||
|
if (channel.Id <= 0) return;
|
||||||
|
|
||||||
var fetchInitialMsgReq = new GetMessagesRequest(channel);
|
var fetchInitialMsgReq = new GetMessagesRequest(channel);
|
||||||
fetchInitialMsgReq.Success += handleChannelMessages;
|
fetchInitialMsgReq.Success += messages =>
|
||||||
fetchInitialMsgReq.Failure += exception => Logger.Error(exception, $"Failed to fetch inital messages for the channel {channel.Name}");
|
{
|
||||||
|
handleChannelMessages(messages);
|
||||||
|
channel.MessagesLoaded = true; // this will mark the channel as having received messages even if tehre were none.
|
||||||
|
};
|
||||||
|
|
||||||
api.Queue(fetchInitialMsgReq);
|
api.Queue(fetchInitialMsgReq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,7 +287,11 @@ namespace osu.Game.Online.Chat
|
|||||||
if (channel.Type == ChannelType.Public && !channel.Joined)
|
if (channel.Type == ChannelType.Public && !channel.Joined)
|
||||||
{
|
{
|
||||||
var req = new JoinChannelRequest(channel, api.LocalUser);
|
var req = new JoinChannelRequest(channel, api.LocalUser);
|
||||||
req.Success += () => JoinChannel(channel);
|
req.Success += () =>
|
||||||
|
{
|
||||||
|
channel.Joined.Value = true;
|
||||||
|
JoinChannel(channel);
|
||||||
|
};
|
||||||
req.Failure += ex => LeaveChannel(channel);
|
req.Failure += ex => LeaveChannel(channel);
|
||||||
api.Queue(req);
|
api.Queue(req);
|
||||||
return;
|
return;
|
||||||
@ -246,11 +301,10 @@ namespace osu.Game.Online.Chat
|
|||||||
if (CurrentChannel.Value == null)
|
if (CurrentChannel.Value == null)
|
||||||
CurrentChannel.Value = channel;
|
CurrentChannel.Value = channel;
|
||||||
|
|
||||||
if (!channel.Joined.Value)
|
if (!channel.MessagesLoaded)
|
||||||
{
|
{
|
||||||
// let's fetch a small number of messages to bring us up-to-date with the backlog.
|
// let's fetch a small number of messages to bring us up-to-date with the backlog.
|
||||||
fetchInitalMessages(channel);
|
fetchInitalMessages(channel);
|
||||||
channel.Joined.Value = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -274,9 +328,6 @@ namespace osu.Game.Online.Chat
|
|||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case APIState.Online:
|
case APIState.Online:
|
||||||
if (JoinedChannels.Count == 0)
|
|
||||||
initializeDefaultChannels();
|
|
||||||
|
|
||||||
fetchUpdates();
|
fetchUpdates();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -289,6 +340,8 @@ namespace osu.Game.Online.Chat
|
|||||||
private long lastMessageId;
|
private long lastMessageId;
|
||||||
private const int update_poll_interval = 1000;
|
private const int update_poll_interval = 1000;
|
||||||
|
|
||||||
|
private bool channelsInitialised;
|
||||||
|
|
||||||
private void fetchUpdates()
|
private void fetchUpdates()
|
||||||
{
|
{
|
||||||
fetchMessagesScheduleder?.Cancel();
|
fetchMessagesScheduleder?.Cancel();
|
||||||
@ -302,7 +355,20 @@ namespace osu.Game.Online.Chat
|
|||||||
{
|
{
|
||||||
foreach (var channel in updates.Presence)
|
foreach (var channel in updates.Presence)
|
||||||
{
|
{
|
||||||
JoinChannel(AvailableChannels.FirstOrDefault(c => c.Id == channel.Id) ?? channel);
|
if (!channel.Joined.Value)
|
||||||
|
{
|
||||||
|
// we received this from the server so should mark the channel already joined.
|
||||||
|
channel.Joined.Value = true;
|
||||||
|
|
||||||
|
JoinChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!channelsInitialised)
|
||||||
|
{
|
||||||
|
channelsInitialised = true;
|
||||||
|
// we want this to run after the first presence so we can see if the user is in any channels already.
|
||||||
|
initializeChannels();
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: handle left channels
|
//todo: handle left channels
|
||||||
|
Loading…
Reference in New Issue
Block a user