mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 17:07:38 +08:00
Implement Private chat
This commit is contained in:
parent
a70b329155
commit
a48ccb5603
30
osu.Game/Online/API/Requests/GetUserMessagesRequest.cs
Normal file
30
osu.Game/Online/API/Requests/GetUserMessagesRequest.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// 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.Collections.Generic;
|
||||
using osu.Framework.IO.Network;
|
||||
using osu.Game.Online.Chat;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetUserMessagesRequest : APIRequest<List<Message>>
|
||||
{
|
||||
private long? since;
|
||||
|
||||
public GetUserMessagesRequest(long? sinceId = null)
|
||||
{
|
||||
since = sinceId;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
{
|
||||
var request = base.CreateWebRequest();
|
||||
if (since.HasValue)
|
||||
request.AddParameter(@"since", since.Value.ToString());
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
protected override string Target => @"chat/messages/private";
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ using osu.Framework.Logging;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
@ -39,12 +40,18 @@ namespace osu.Game.Online.Chat
|
||||
/// 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>();
|
||||
|
||||
private APIAccess api;
|
||||
private readonly Scheduler scheduler;
|
||||
private ScheduledDelegate fetchMessagesScheduleder;
|
||||
private GetChannelMessagesRequest fetchChannelMsgReq;
|
||||
private GetUserMessagesRequest fetchUserMsgReq;
|
||||
private long? lastChannelMsgId;
|
||||
private long? lastUserMsgId;
|
||||
|
||||
public ChatManager(Scheduler scheduler)
|
||||
{
|
||||
@ -56,7 +63,6 @@ namespace osu.Game.Online.Chat
|
||||
{
|
||||
if (chatBase is ChannelChat channel && !JoinedChannels.Contains(channel))
|
||||
JoinedChannels.Add(channel);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -127,6 +133,63 @@ namespace osu.Game.Online.Chat
|
||||
{
|
||||
if (fetchChannelMsgReq == null)
|
||||
fetchNewChannelMessages();
|
||||
|
||||
if (fetchUserMsgReq == null)
|
||||
fetchNewUserMessages();
|
||||
}
|
||||
|
||||
private void fetchNewUserMessages()
|
||||
{
|
||||
fetchUserMsgReq = new GetUserMessagesRequest(lastUserMsgId);
|
||||
|
||||
fetchUserMsgReq.Success += messages =>
|
||||
{
|
||||
handleUserMessages(messages);
|
||||
lastUserMsgId = messages.LastOrDefault()?.Id ?? lastUserMsgId;
|
||||
fetchUserMsgReq = null;
|
||||
};
|
||||
fetchUserMsgReq.Failure += exception => Logger.Error(exception, "Fetching user messages failed.");
|
||||
|
||||
api.Queue(fetchUserMsgReq);
|
||||
}
|
||||
|
||||
private void handleUserMessages(IEnumerable<Message> messages)
|
||||
{
|
||||
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);
|
||||
|
||||
foreach (var messageGroup in incomingMessagesGroups)
|
||||
{
|
||||
var targetUser = messageGroup.First().Sender;
|
||||
var chat = OpenedUserChats.FirstOrDefault(c => c.User.Id == targetUser.Id);
|
||||
|
||||
if (chat == null)
|
||||
{
|
||||
chat = new UserChat(targetUser);
|
||||
OpenedUserChats.Add(chat);
|
||||
}
|
||||
|
||||
chat.AddNewMessages(messageGroup.ToArray());
|
||||
var outgoingTargetMessages = outgoingMessagesGroups.FirstOrDefault(g => g.Key == targetUser.Id);
|
||||
chat.AddNewMessages(outgoingTargetMessages.ToArray());
|
||||
}
|
||||
|
||||
var withoutReplyGroups = outgoingMessagesGroups.Where(g => OpenedUserChats.All(m => m.ChatID != g.Key));
|
||||
|
||||
foreach (var withoutReplyGroup in withoutReplyGroups)
|
||||
{
|
||||
var getUserRequest = new GetUserRequest(withoutReplyGroup.First().TargetId);
|
||||
getUserRequest.Success += user =>
|
||||
{
|
||||
var chat = new UserChat(user);
|
||||
|
||||
chat.AddNewMessages(withoutReplyGroup.ToArray());
|
||||
OpenedUserChats.Add(chat);
|
||||
};
|
||||
|
||||
api.Queue(getUserRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchNewChannelMessages()
|
||||
@ -135,6 +198,8 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
fetchChannelMsgReq.Success += messages =>
|
||||
{
|
||||
if (messages == null)
|
||||
return;
|
||||
handleChannelMessages(messages);
|
||||
lastChannelMsgId = messages.LastOrDefault()?.Id ?? lastChannelMsgId;
|
||||
fetchChannelMsgReq = null;
|
||||
@ -163,7 +228,13 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
channels.Where(channel => defaultChannels.Contains(channel.Name))
|
||||
.Where(channel => JoinedChannels.All(c => c.ChatID != channel.ChatID))
|
||||
.ForEach(channel => JoinedChannels.Add(channel));
|
||||
.ForEach(channel =>
|
||||
{
|
||||
JoinedChannels.Add(channel);
|
||||
var fetchInitialMsgReq = new GetChannelMessagesRequest(new[] {channel}, null);
|
||||
fetchInitialMsgReq.Success += handleChannelMessages;
|
||||
api.Queue(fetchInitialMsgReq);
|
||||
});
|
||||
|
||||
fetchNewMessages();
|
||||
};
|
||||
@ -185,7 +256,9 @@ namespace osu.Game.Online.Chat
|
||||
break;
|
||||
default:
|
||||
fetchChannelMsgReq?.Cancel();
|
||||
fetchChannelMsgReq = null;
|
||||
fetchMessagesScheduleder?.Cancel();
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
23
osu.Game/Online/Chat/UserChat.cs
Normal file
23
osu.Game/Online/Chat/UserChat.cs
Normal file
@ -0,0 +1,23 @@
|
||||
// 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.Game.Users;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
{
|
||||
public class UserChat : ChatBase
|
||||
{
|
||||
public User User { get; }
|
||||
|
||||
public UserChat(User user, Message[] messages = null)
|
||||
{
|
||||
User = user ?? throw new ArgumentNullException(nameof(user));
|
||||
|
||||
if (messages != null) AddNewMessages(messages);
|
||||
}
|
||||
|
||||
public override TargetType Target => TargetType.User;
|
||||
public override long ChatID => User.Id;
|
||||
}
|
||||
}
|
@ -29,7 +29,6 @@ using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Input.Bindings;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Skinning;
|
||||
using OpenTK.Graphics;
|
||||
|
@ -21,7 +21,7 @@ using osu.Game.Graphics.Containers;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class ChatTabControl : OsuTabControl<ChannelChat>
|
||||
public class ChannelTabControl : OsuTabControl<ChannelChat>
|
||||
{
|
||||
private const float shear_width = 10;
|
||||
|
||||
@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Chat
|
||||
|
||||
private readonly ChannelTabItem.ChannelSelectorTabItem selectorTab;
|
||||
|
||||
public ChatTabControl()
|
||||
public ChannelTabControl()
|
||||
{
|
||||
TabContainer.Margin = new MarginPadding { Left = 50 };
|
||||
TabContainer.Spacing = new Vector2(-shear_width, 0);
|
||||
@ -51,6 +51,13 @@ namespace osu.Game.Overlays.Chat
|
||||
ChannelSelectorActive.BindTo(selectorTab.Active);
|
||||
}
|
||||
|
||||
public void DeselectAll()
|
||||
{
|
||||
if (SelectedTab != null)
|
||||
SelectedTab.Active.Value = false;
|
||||
SelectedTab = null;
|
||||
}
|
||||
|
||||
protected override void AddTabItem(TabItem<ChannelChat> item, bool addToDropdown = true)
|
||||
{
|
||||
if (item != selectorTab && TabContainer.GetLayoutPosition(selectorTab) < float.MaxValue)
|
55
osu.Game/Overlays/Chat/ChatTabItemCloseButton.cs
Normal file
55
osu.Game/Overlays/Chat/ChatTabItemCloseButton.cs
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
||||
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Input;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class ChatTabItemCloseButton : OsuClickableContainer
|
||||
{
|
||||
private readonly SpriteIcon icon;
|
||||
|
||||
public ChatTabItemCloseButton()
|
||||
{
|
||||
Size = new Vector2(20);
|
||||
|
||||
Child = icon = new SpriteIcon
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(0.75f),
|
||||
Icon = FontAwesome.fa_close,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
};
|
||||
}
|
||||
|
||||
protected override bool OnMouseDown(InputState state, MouseDownEventArgs args)
|
||||
{
|
||||
icon.ScaleTo(0.5f, 1000, Easing.OutQuint);
|
||||
return base.OnMouseDown(state, args);
|
||||
}
|
||||
|
||||
protected override bool OnMouseUp(InputState state, MouseUpEventArgs args)
|
||||
{
|
||||
icon.ScaleTo(0.75f, 1000, Easing.OutElastic);
|
||||
return base.OnMouseUp(state, args);
|
||||
}
|
||||
|
||||
protected override bool OnHover(InputState state)
|
||||
{
|
||||
icon.FadeColour(Color4.Red, 200, Easing.OutQuint);
|
||||
return base.OnHover(state);
|
||||
}
|
||||
|
||||
protected override void OnHoverLost(InputState state)
|
||||
{
|
||||
icon.FadeColour(Color4.White, 200, Easing.OutQuint);
|
||||
base.OnHoverLost(state);
|
||||
}
|
||||
}
|
||||
}
|
51
osu.Game/Overlays/Chat/UserChatTabControl.cs
Normal file
51
osu.Game/Overlays/Chat/UserChatTabControl.cs
Normal file
@ -0,0 +1,51 @@
|
||||
// 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.Graphics.UserInterface;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Chat;
|
||||
using OpenTK;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class UserChatTabControl : OsuTabControl<UserChat>
|
||||
{
|
||||
protected override TabItem<UserChat> CreateTabItem(UserChat value) => new UserChatTabItem(value) { OnRequestClose = tabCloseRequested };
|
||||
|
||||
public Action<UserChat> OnRequestLeave;
|
||||
|
||||
public UserChatTabControl()
|
||||
{
|
||||
TabContainer.Spacing = new Vector2(-10, 0);
|
||||
TabContainer.Masking = false;
|
||||
}
|
||||
|
||||
protected override void AddTabItem(TabItem<UserChat> item, bool addToDropdown = true)
|
||||
{
|
||||
base.AddTabItem(item, addToDropdown);
|
||||
|
||||
if (SelectedTab == null)
|
||||
SelectTab(item);
|
||||
}
|
||||
|
||||
private void tabCloseRequested(TabItem<UserChat> priv)
|
||||
{
|
||||
int totalTabs = TabContainer.Count -1; // account for selectorTab
|
||||
int currentIndex = MathHelper.Clamp(TabContainer.IndexOf(priv), 1, totalTabs);
|
||||
|
||||
if (priv == SelectedTab && totalTabs > 1)
|
||||
// Select the tab after tab-to-be-removed's index, or the tab before if current == last
|
||||
SelectTab(TabContainer[currentIndex == totalTabs ? currentIndex - 1 : currentIndex + 1]);
|
||||
|
||||
OnRequestLeave?.Invoke(priv.Value);
|
||||
}
|
||||
|
||||
public void DeselectAll()
|
||||
{
|
||||
if (SelectedTab != null)
|
||||
SelectedTab.Active.Value = false;
|
||||
SelectedTab = null;
|
||||
}
|
||||
}
|
||||
}
|
201
osu.Game/Overlays/Chat/UserChatTabItem.cs
Normal file
201
osu.Game/Overlays/Chat/UserChatTabItem.cs
Normal file
@ -0,0 +1,201 @@
|
||||
// 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.Allocation;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.UserInterface;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Screens.Menu;
|
||||
using osu.Game.Users;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.Chat
|
||||
{
|
||||
public class UserChatTabItem : TabItem<UserChat>
|
||||
{
|
||||
private static readonly Vector2 shear = new Vector2(1f / 5f, 0);
|
||||
|
||||
public override bool IsRemovable => true;
|
||||
|
||||
private readonly Box highlightBox;
|
||||
private readonly Container backgroundContainer;
|
||||
private readonly Box backgroundBox;
|
||||
private readonly OsuSpriteText username;
|
||||
private readonly ChatTabItemCloseButton closeButton;
|
||||
|
||||
public UserChatTabItem(UserChat value)
|
||||
: base(value)
|
||||
{
|
||||
AutoSizeAxes = Axes.X;
|
||||
RelativeSizeAxes = Axes.Y;
|
||||
Origin = Anchor.BottomRight;
|
||||
Anchor = Anchor.BottomRight;
|
||||
EdgeEffect = deactivateEdgeEffect;
|
||||
Masking = false;
|
||||
Shear = shear;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
backgroundBox = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
EdgeSmoothness = new Vector2(1, 0),
|
||||
},
|
||||
}
|
||||
},
|
||||
highlightBox = new Box
|
||||
{
|
||||
Width = 5,
|
||||
BypassAutoSizeAxes = Axes.X,
|
||||
Alpha = 0,
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
EdgeSmoothness = new Vector2(1, 0),
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Colour = new OsuColour().Yellow
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Masking = true,
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Child = new FlowContainerWithOrigin
|
||||
{
|
||||
AutoSizeAxes = Axes.X,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
X = -5,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Origin = Anchor.TopLeft,
|
||||
Anchor = Anchor.TopLeft,
|
||||
Shear = -shear,
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
AutoSizeAxes = Axes.X,
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
Horizontal = 5
|
||||
},
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
|
||||
new SpriteIcon
|
||||
{
|
||||
Icon = FontAwesome.fa_eercast,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(1.2f),
|
||||
X = -5,
|
||||
Y = 5,
|
||||
Anchor = Anchor.Centre,
|
||||
Colour = new OsuColour().BlueDarker,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new CircularContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
Scale = new Vector2(0.95f),
|
||||
AutoSizeAxes = Axes.X,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Masking = true,
|
||||
Child = new Avatar(value.User)
|
||||
{
|
||||
Size = new Vector2(ChatOverlay.TAB_AREA_HEIGHT),
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
username = new OsuSpriteText
|
||||
{
|
||||
Origin = Anchor.CentreLeft,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Text = value.User.Username,
|
||||
Margin = new MarginPadding(1),
|
||||
TextSize = 18,
|
||||
},
|
||||
closeButton = new ChatTabItemCloseButton
|
||||
{
|
||||
Height = 1,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
RelativeSizeAxes = Axes.Y,
|
||||
|
||||
Action = delegate
|
||||
{
|
||||
if (IsRemovable) OnRequestClose?.Invoke(this);
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Action<UserChatTabItem> OnRequestClose;
|
||||
|
||||
private readonly EdgeEffectParameters activateEdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 30,
|
||||
Colour = Color4.Black.Opacity(0.3f),
|
||||
};
|
||||
|
||||
protected override void OnActivated()
|
||||
{
|
||||
const int activate_length = 1000;
|
||||
|
||||
backgroundBox.ResizeHeightTo(1.1f, activate_length, Easing.OutQuint);
|
||||
highlightBox.ResizeHeightTo(1.1f, activate_length, Easing.OutQuint);
|
||||
highlightBox.FadeIn(activate_length, Easing.OutQuint);
|
||||
username.FadeIn(activate_length, Easing.OutQuint);
|
||||
username.ScaleTo(new Vector2(1, 1), activate_length, Easing.OutQuint);
|
||||
closeButton.ScaleTo(new Vector2(1, 1), activate_length, Easing.OutQuint);
|
||||
closeButton.FadeIn(activate_length, Easing.OutQuint);
|
||||
TweenEdgeEffectTo(activateEdgeEffect, activate_length);
|
||||
}
|
||||
|
||||
private readonly EdgeEffectParameters deactivateEdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.0f),
|
||||
};
|
||||
|
||||
protected override void OnDeactivated()
|
||||
{
|
||||
const int deactivate_length = 500;
|
||||
|
||||
backgroundBox.ResizeHeightTo(1, deactivate_length, Easing.OutQuint);
|
||||
highlightBox.ResizeHeightTo(1, deactivate_length, Easing.OutQuint);
|
||||
highlightBox.FadeOut(deactivate_length, Easing.OutQuint);
|
||||
username.FadeOut(deactivate_length, Easing.OutQuint);
|
||||
username.ScaleTo(new Vector2(0, 1), deactivate_length, Easing.OutQuint);
|
||||
closeButton.FadeOut(deactivate_length, Easing.OutQuint);
|
||||
closeButton.ScaleTo(new Vector2(0, 1), deactivate_length, Easing.OutQuint);
|
||||
TweenEdgeEffectTo(deactivateEdgeEffect, deactivate_length);
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours)
|
||||
{
|
||||
backgroundBox.Colour = Value.User.Colour != null ? OsuColour.FromHex(Value.User.Colour) : colours.BlueDark;
|
||||
}
|
||||
}
|
||||
}
|
@ -45,7 +45,8 @@ namespace osu.Game.Overlays
|
||||
|
||||
public const float TAB_AREA_HEIGHT = 50;
|
||||
|
||||
private readonly ChatTabControl channelTabs;
|
||||
private readonly ChannelTabControl channelTabs;
|
||||
private readonly UserChatTabControl userTabs;
|
||||
|
||||
private readonly Container chatContainer;
|
||||
private readonly Container tabsArea;
|
||||
@ -154,17 +155,23 @@ namespace osu.Game.Overlays
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
},
|
||||
channelTabs = new ChatTabControl
|
||||
channelTabs = new ChannelTabControl
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
OnRequestLeave = channel => chatManager.JoinedChannels.Remove(channel),
|
||||
},
|
||||
userTabs = new UserChatTabControl
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
OnRequestLeave = privateChat => chatManager.OpenedUserChats.Remove(privateChat),
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
userTabs.Current.ValueChanged += user => chatManager.CurrentChat.Value = user;
|
||||
channelTabs.Current.ValueChanged += newChannel => chatManager.CurrentChat.Value = newChannel;
|
||||
channelTabs.ChannelSelectorActive.ValueChanged += value => channelSelection.State = value ? Visibility.Visible : Visibility.Hidden;
|
||||
channelSelection.StateChanged += state =>
|
||||
@ -241,7 +248,16 @@ namespace osu.Game.Overlays
|
||||
textbox.Current.Disabled = chat.ReadOnly;
|
||||
|
||||
if (chat is ChannelChat channelChat)
|
||||
{
|
||||
channelTabs.Current.Value = channelChat;
|
||||
userTabs.DeselectAll();
|
||||
}
|
||||
|
||||
if (chat is UserChat userChat)
|
||||
{
|
||||
userTabs.Current.Value = userChat;
|
||||
channelTabs.DeselectAll();
|
||||
}
|
||||
|
||||
var loaded = loadedChannels.Find(d => d.Chat == chat);
|
||||
if (loaded == null)
|
||||
@ -355,6 +371,23 @@ namespace osu.Game.Overlays
|
||||
chatManager.CurrentChat.ValueChanged += currentChatChanged;
|
||||
chatManager.JoinedChannels.CollectionChanged += joinedChannelsChanged;
|
||||
chatManager.AvailableChannels.CollectionChanged += availableChannelsChanged;
|
||||
chatManager.OpenedUserChats.CollectionChanged += openedUserChatsChanged;
|
||||
}
|
||||
|
||||
private void openedUserChatsChanged(object sender, NotifyCollectionChangedEventArgs args)
|
||||
{
|
||||
switch (args.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
userTabs.AddItem(args.NewItems[0] as UserChat);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
userTabs.RemoveItem(args.OldItems[0] as UserChat);
|
||||
break;
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
userTabs.Clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void postMessage(TextBox textbox, bool newText)
|
||||
|
Loading…
Reference in New Issue
Block a user