mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 15:44:04 +09:00
Rename everything into channel and remove everything chat
This commit is contained in:
@ -1,22 +1,55 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Configuration;
|
||||
using osu.Framework.Lists;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
public abstract class ChatBase
|
||||
public class Channel
|
||||
{
|
||||
public const int MAX_HISTORY = 300;
|
||||
public bool ReadOnly { get; } = false;
|
||||
public abstract TargetType Target { get; }
|
||||
public abstract long ChatID { get; }
|
||||
public Bindable<bool> Joined = new Bindable<bool>();
|
||||
|
||||
[JsonProperty(@"name")]
|
||||
public string Name;
|
||||
|
||||
[JsonProperty(@"description")]
|
||||
public string Topic;
|
||||
|
||||
[JsonProperty(@"type")]
|
||||
public string Type;
|
||||
|
||||
[JsonProperty(@"channel_id")]
|
||||
public long Id;
|
||||
|
||||
[JsonConstructor]
|
||||
public Channel()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contructs a privatechannel
|
||||
/// TODO this class needs to be serialized from something like channels/private, instead of creating from a contructor
|
||||
/// </summary>
|
||||
/// <param name="user">The user </param>
|
||||
public Channel(User user)
|
||||
{
|
||||
Target = TargetType.User;
|
||||
Name = user.Username;
|
||||
Id = user.Id;
|
||||
JoinedUsers.Add(user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains every joined user except yourself
|
||||
/// </summary>
|
||||
public ObservableCollection<User> JoinedUsers = new ObservableCollection<User>();
|
||||
public readonly SortedList<Message> Messages = new SortedList<Message>(Comparer<Message>.Default);
|
||||
private readonly List<LocalEchoMessage> pendingMessages = new List<LocalEchoMessage>();
|
||||
|
||||
@ -24,6 +57,10 @@ namespace osu.Game.Online.Chat
|
||||
public event Action<LocalEchoMessage, Message> PendingMessageResolved;
|
||||
public event Action<Message> MessageRemoved;
|
||||
|
||||
public Bindable<bool> Joined = new Bindable<bool>();
|
||||
public TargetType Target { get; set; }
|
||||
public bool ReadOnly { get; set; }
|
||||
|
||||
public void AddLocalEcho(LocalEchoMessage message)
|
||||
{
|
||||
pendingMessages.Add(message);
|
||||
@ -43,16 +80,8 @@ namespace osu.Game.Online.Chat
|
||||
NewMessagesArrived?.Invoke(messages);
|
||||
}
|
||||
|
||||
private void purgeOldMessages()
|
||||
{
|
||||
// never purge local echos
|
||||
int messageCount = Messages.Count - pendingMessages.Count;
|
||||
if (messageCount > MAX_HISTORY)
|
||||
Messages.RemoveRange(0, messageCount - MAX_HISTORY);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replace or remove a message from the chat.
|
||||
/// Replace or remove a message from the channel.
|
||||
/// </summary>
|
||||
/// <param name="echo">The local echo message (client-side).</param>
|
||||
/// <param name="final">The response message, or null if the message became invalid.</param>
|
||||
@ -81,5 +110,14 @@ namespace osu.Game.Online.Chat
|
||||
PendingMessageResolved?.Invoke(echo, final);
|
||||
}
|
||||
|
||||
private void purgeOldMessages()
|
||||
{
|
||||
// never purge local echos
|
||||
int messageCount = Messages.Count - pendingMessages.Count;
|
||||
if (messageCount > MAX_HISTORY)
|
||||
Messages.RemoveRange(0, messageCount - MAX_HISTORY);
|
||||
}
|
||||
|
||||
public override string ToString() => Name;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
// 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;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
public class ChannelChat : ChatBase
|
||||
{
|
||||
[JsonProperty(@"name")]
|
||||
public string Name;
|
||||
|
||||
[JsonProperty(@"description")]
|
||||
public string Topic;
|
||||
|
||||
[JsonProperty(@"type")]
|
||||
public string Type;
|
||||
|
||||
[JsonProperty(@"channel_id")]
|
||||
public int Id;
|
||||
|
||||
[JsonConstructor]
|
||||
public ChannelChat()
|
||||
{
|
||||
}
|
||||
|
||||
public override string ToString() => Name;
|
||||
public override long ChatID => Id;
|
||||
public override TargetType Target => TargetType.Channel;
|
||||
}
|
||||
}
|
@ -17,9 +17,9 @@ using osu.Game.Users;
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages everything chat related
|
||||
/// Manages everything channel related
|
||||
/// </summary>
|
||||
public class ChatManager : Component, IOnlineComponent
|
||||
public class ChannelManager : Component, IOnlineComponent
|
||||
{
|
||||
/// <summary>
|
||||
/// The channels the player joins on startup
|
||||
@ -30,21 +30,17 @@ namespace osu.Game.Online.Chat
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The currently opened chat
|
||||
/// The currently opened channel
|
||||
/// </summary>
|
||||
public Bindable<ChatBase> CurrentChat { get; } = new Bindable<ChatBase>();
|
||||
public Bindable<Channel> CurrentChannel { get; } = new Bindable<Channel>();
|
||||
/// <summary>
|
||||
/// The Channels the player has joined
|
||||
/// </summary>
|
||||
public ObservableCollection<ChannelChat> JoinedChannels { get; } = new ObservableCollection<ChannelChat>();
|
||||
public ObservableCollection<Channel> JoinedChannels { get; } = new ObservableCollection<Channel>();
|
||||
/// <summary>
|
||||
/// The channels available for the player to join
|
||||
/// </summary>
|
||||
public ObservableCollection<ChannelChat> AvailableChannels { get; } = new ObservableCollection<ChannelChat>();
|
||||
/// <summary>
|
||||
/// The user chats opened.
|
||||
/// </summary>
|
||||
public ObservableCollection<UserChat> OpenedUserChats { get; } = new ObservableCollection<UserChat>();
|
||||
public ObservableCollection<Channel> AvailableChannels { get; } = new ObservableCollection<Channel>();
|
||||
|
||||
private APIAccess api;
|
||||
private readonly Scheduler scheduler;
|
||||
@ -54,68 +50,49 @@ namespace osu.Game.Online.Chat
|
||||
private long? lastChannelMsgId;
|
||||
private long? lastUserMsgId;
|
||||
|
||||
public void OpenChannelChat(string name)
|
||||
public void OpenChannel(string name)
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
|
||||
CurrentChat.Value = AvailableChannels.FirstOrDefault(c => c.Name == name)
|
||||
CurrentChannel.Value = AvailableChannels.FirstOrDefault(c => c.Name == name)
|
||||
?? throw new ArgumentException($"Channel {name} was not found.");
|
||||
}
|
||||
|
||||
public void OpenUserChat(long userId)
|
||||
{
|
||||
var chat = OpenedUserChats.FirstOrDefault(c => c.ChatID == userId);
|
||||
|
||||
if (chat == null)
|
||||
{
|
||||
chat = new UserChat(new User
|
||||
{
|
||||
Id = userId
|
||||
});
|
||||
chat.RequestDetails(api);
|
||||
}
|
||||
|
||||
CurrentChat.Value = chat;
|
||||
}
|
||||
|
||||
public void OpenUserChat(User user)
|
||||
public void OpenUserChannel(User user)
|
||||
{
|
||||
if (user == null)
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
|
||||
CurrentChat.Value = OpenedUserChats.FirstOrDefault(c => c.ChatID == user.Id)
|
||||
?? new UserChat(user);
|
||||
CurrentChannel.Value = JoinedChannels.FirstOrDefault(c => c.Target == TargetType.User && c.Id == user.Id)
|
||||
?? new Channel(user);
|
||||
}
|
||||
|
||||
public ChatManager(Scheduler scheduler)
|
||||
public ChannelManager(Scheduler scheduler)
|
||||
{
|
||||
this.scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));
|
||||
CurrentChat.ValueChanged += currentChatChanged;
|
||||
CurrentChannel.ValueChanged += currentChannelChanged;
|
||||
}
|
||||
|
||||
private void currentChatChanged(ChatBase chatBase)
|
||||
private void currentChannelChanged(Channel channel)
|
||||
{
|
||||
if (chatBase is ChannelChat channel && !JoinedChannels.Contains(channel))
|
||||
if (!JoinedChannels.Contains(channel))
|
||||
JoinedChannels.Add(channel);
|
||||
|
||||
if (chatBase is UserChat userChat && !OpenedUserChats.Contains(userChat))
|
||||
OpenedUserChats.Add(userChat);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Posts a message to the currently opened chat.
|
||||
/// Posts a message to the currently opened channel.
|
||||
/// </summary>
|
||||
/// <param name="text">The message text that is going to be posted</param>
|
||||
/// <param name="isAction">Is true if the message is an action, e.g.: user is currently eating </param>
|
||||
public void PostMessage(string text, bool isAction = false)
|
||||
{
|
||||
if (CurrentChat.Value == null)
|
||||
if (CurrentChannel.Value == null)
|
||||
return;
|
||||
|
||||
if (!api.IsLoggedIn)
|
||||
{
|
||||
CurrentChat.Value.AddNewMessages(new ErrorMessage("Please sign in to participate in chat!"));
|
||||
CurrentChannel.Value.AddNewMessages(new ErrorMessage("Please sign in to participate in chat!"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -123,23 +100,23 @@ namespace osu.Game.Online.Chat
|
||||
{
|
||||
Sender = api.LocalUser.Value,
|
||||
Timestamp = DateTimeOffset.Now,
|
||||
TargetType = CurrentChat.Value.Target,
|
||||
TargetId = CurrentChat.Value.ChatID,
|
||||
TargetType = CurrentChannel.Value.Target,
|
||||
TargetId = CurrentChannel.Value.Id,
|
||||
IsAction = isAction,
|
||||
Content = text
|
||||
};
|
||||
|
||||
CurrentChat.Value.AddLocalEcho(message);
|
||||
CurrentChannel.Value.AddLocalEcho(message);
|
||||
|
||||
var req = new PostMessageRequest(message);
|
||||
req.Failure += e => CurrentChat.Value?.ReplaceMessage(message, null);
|
||||
req.Success += m => CurrentChat.Value?.ReplaceMessage(message, m);
|
||||
req.Failure += e => CurrentChannel.Value?.ReplaceMessage(message, null);
|
||||
req.Success += m => CurrentChannel.Value?.ReplaceMessage(message, m);
|
||||
api.Queue(req);
|
||||
}
|
||||
|
||||
public void PostCommand(string text)
|
||||
{
|
||||
if (CurrentChat.Value == null)
|
||||
if (CurrentChannel.Value == null)
|
||||
return;
|
||||
|
||||
var parameters = text.Split(new[] { ' ' }, 2);
|
||||
@ -151,18 +128,18 @@ namespace osu.Game.Online.Chat
|
||||
case "me":
|
||||
if (string.IsNullOrWhiteSpace(content))
|
||||
{
|
||||
CurrentChat.Value.AddNewMessages(new ErrorMessage("Usage: /me [action]"));
|
||||
CurrentChannel.Value.AddNewMessages(new ErrorMessage("Usage: /me [action]"));
|
||||
break;
|
||||
}
|
||||
PostMessage(content, true);
|
||||
break;
|
||||
|
||||
case "help":
|
||||
CurrentChat.Value.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]"));
|
||||
CurrentChannel.Value.AddNewMessages(new InfoMessage("Supported commands: /help, /me [action]"));
|
||||
break;
|
||||
|
||||
default:
|
||||
CurrentChat.Value.AddNewMessages(new ErrorMessage($@"""/{command}"" is not supported! For a list of supported commands see /help"));
|
||||
CurrentChannel.Value.AddNewMessages(new ErrorMessage($@"""/{command}"" is not supported! For a list of supported commands see /help"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -193,6 +170,8 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
private void handleUserMessages(IEnumerable<Message> messages)
|
||||
{
|
||||
var joinedUserChannels = JoinedChannels.Where(c => c.Target == TargetType.User).ToList();
|
||||
|
||||
var outgoingMessages = messages.Where(m => m.Sender.Id == api.LocalUser.Value.Id);
|
||||
var outgoingMessagesGroups = outgoingMessages.GroupBy(m => m.TargetId);
|
||||
var incomingMessagesGroups = messages.Except(outgoingMessages).GroupBy(m => m.UserId);
|
||||
@ -200,35 +179,43 @@ namespace osu.Game.Online.Chat
|
||||
foreach (var messageGroup in incomingMessagesGroups)
|
||||
{
|
||||
var targetUser = messageGroup.First().Sender;
|
||||
var chat = OpenedUserChats.FirstOrDefault(c => c.User.Id == targetUser.Id);
|
||||
var channel = joinedUserChannels.FirstOrDefault(c => c.Id == targetUser.Id);
|
||||
|
||||
if (chat == null)
|
||||
if (channel == null)
|
||||
{
|
||||
chat = new UserChat(targetUser);
|
||||
OpenedUserChats.Add(chat);
|
||||
channel = new Channel(targetUser);
|
||||
JoinedChannels.Add(channel);
|
||||
joinedUserChannels.Add(channel);
|
||||
}
|
||||
|
||||
chat.AddNewMessages(messageGroup.ToArray());
|
||||
channel.AddNewMessages(messageGroup.ToArray());
|
||||
var outgoingTargetMessages = outgoingMessagesGroups.FirstOrDefault(g => g.Key == targetUser.Id);
|
||||
if (outgoingTargetMessages != null)
|
||||
chat.AddNewMessages(outgoingTargetMessages.ToArray());
|
||||
channel.AddNewMessages(outgoingTargetMessages.ToArray());
|
||||
}
|
||||
|
||||
var withoutReplyGroups = outgoingMessagesGroups.Where(g => OpenedUserChats.All(m => m.ChatID != g.Key));
|
||||
var withoutReplyGroups = outgoingMessagesGroups.Where(g => joinedUserChannels.All(m => m.Id != g.Key));
|
||||
|
||||
foreach (var withoutReplyGroup in withoutReplyGroups)
|
||||
{
|
||||
var chat = new UserChat(new User { Id = withoutReplyGroup.First().TargetId });
|
||||
var userReq = new GetUserRequest(withoutReplyGroup.First().TargetId);
|
||||
|
||||
chat.AddNewMessages(withoutReplyGroup.ToArray());
|
||||
OpenedUserChats.Add(chat);
|
||||
chat.RequestDetails(api);
|
||||
userReq.Failure += exception => Logger.Error(exception, "Failed to get user informations.");
|
||||
userReq.Success += user =>
|
||||
{
|
||||
var channel = new Channel(user);
|
||||
|
||||
channel.AddNewMessages(withoutReplyGroup.ToArray());
|
||||
JoinedChannels.Add(channel);
|
||||
};
|
||||
|
||||
api.Queue(userReq);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchNewChannelMessages()
|
||||
{
|
||||
fetchChannelMsgReq = new GetChannelMessagesRequest(JoinedChannels, lastChannelMsgId);
|
||||
fetchChannelMsgReq = new GetChannelMessagesRequest(JoinedChannels.Where(c => c.Target == TargetType.Channel), lastChannelMsgId);
|
||||
|
||||
fetchChannelMsgReq.Success += messages =>
|
||||
{
|
||||
@ -257,22 +244,24 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
req.Success += channels =>
|
||||
{
|
||||
channels.Where(channel => AvailableChannels.All(c => c.ChatID != channel.ChatID))
|
||||
channels.Where(channel => AvailableChannels.All(c => c.Id != channel.Id))
|
||||
.ForEach(channel => AvailableChannels.Add(channel));
|
||||
|
||||
channels.Where(channel => defaultChannels.Contains(channel.Name))
|
||||
.Where(channel => JoinedChannels.All(c => c.ChatID != channel.ChatID))
|
||||
.Where(channel => JoinedChannels.All(c => c.Id != channel.Id))
|
||||
.ForEach(channel =>
|
||||
{
|
||||
JoinedChannels.Add(channel);
|
||||
|
||||
var fetchInitialMsgReq = new GetChannelMessagesRequest(new[] {channel}, null);
|
||||
fetchInitialMsgReq.Success += handleChannelMessages;
|
||||
fetchInitialMsgReq.Failure += exception => Logger.Error(exception, "Failed to fetch inital messages.");
|
||||
api.Queue(fetchInitialMsgReq);
|
||||
});
|
||||
|
||||
fetchNewMessages();
|
||||
};
|
||||
req.Failure += error => Logger.Error(error, "Fetching channels failed");
|
||||
req.Failure += error => Logger.Error(error, "Fetching channel list failed");
|
||||
|
||||
api.Queue(req);
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
// 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;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
public class UserChat : ChatBase
|
||||
{
|
||||
public User User { get; private set; }
|
||||
public override TargetType Target => TargetType.User;
|
||||
public override long ChatID => User.Id;
|
||||
|
||||
public Action<User> DetailsArrived;
|
||||
|
||||
public UserChat(User user, Message[] messages = null)
|
||||
{
|
||||
User = user ?? throw new ArgumentNullException(nameof(user));
|
||||
|
||||
if (messages != null) AddNewMessages(messages);
|
||||
}
|
||||
|
||||
public void RequestDetails(IAPIProvider api)
|
||||
{
|
||||
if (api == null)
|
||||
throw new ArgumentNullException(nameof(api));
|
||||
|
||||
var req = new GetUserRequest(User.Id);
|
||||
req.Success += user =>
|
||||
{
|
||||
User = user;
|
||||
DetailsArrived?.Invoke(user);
|
||||
};
|
||||
req.Failure += exception => Logger.Error(exception, $"Requesting details for user with Id:{User.Id} failed.");
|
||||
api.Queue(req);
|
||||
}
|
||||
|
||||
public override string ToString() => User.Username ?? User.Id.ToString();
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user