diff --git a/osu-framework b/osu-framework index 682f078b2e..fcf36739bc 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 682f078b2efc82fa19342f499f14c4a8458843d5 +Subproject commit fcf36739bc8a97b43a08ce0b29bd7c67ce1a3547 diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 242a9a8f6a..8b72eedbfd 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -25,15 +25,15 @@ namespace osu.Game.Graphics.UserInterface protected override bool InternalContains(Vector2 screenSpacePos) => base.InternalContains(screenSpacePos) || Dropdown.Contains(screenSpacePos); + private bool isEnumType => typeof(T).IsEnum; + public OsuTabControl() { TabContainer.Spacing = new Vector2(10f, 0f); - if (!typeof(T).IsEnum) - throw new InvalidOperationException("OsuTabControl only supports enums as the generic type argument"); - - foreach (var val in (T[])Enum.GetValues(typeof(T))) - AddItem(val); + if (isEnumType) + foreach (var val in (T[])Enum.GetValues(typeof(T))) + AddItem(val); } [BackgroundDependencyLoader] @@ -136,7 +136,7 @@ namespace osu.Game.Graphics.UserInterface Margin = new MarginPadding { Top = 5, Bottom = 5 }, Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, - Text = (value as Enum)?.GetDescription(), + Text = (value as Enum)?.GetDescription() ?? value.ToString(), TextSize = 14, Font = @"Exo2.0-Bold", // Font should only turn bold when active? }, diff --git a/osu.Game/Online/Chat/Channel.cs b/osu.Game/Online/Chat/Channel.cs index d3bd57a1c9..d159f482a9 100644 --- a/osu.Game/Online/Chat/Channel.cs +++ b/osu.Game/Online/Chat/Channel.cs @@ -27,6 +27,8 @@ namespace osu.Game.Online.Chat //internal bool Joined; + public bool ReadOnly => Name != "#lazer"; + public const int MAX_HISTORY = 300; [JsonConstructor] @@ -53,5 +55,7 @@ namespace osu.Game.Online.Chat if (messageCount > MAX_HISTORY) Messages.RemoveRange(0, messageCount - MAX_HISTORY); } + + public override string ToString() => Name; } } diff --git a/osu.Game/Online/Chat/Drawables/DrawableChannel.cs b/osu.Game/Online/Chat/Drawables/DrawableChannel.cs index e3101e8fd7..d179f851b2 100644 --- a/osu.Game/Online/Chat/Drawables/DrawableChannel.cs +++ b/osu.Game/Online/Chat/Drawables/DrawableChannel.cs @@ -7,32 +7,23 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Primitives; -using osu.Game.Graphics.Sprites; namespace osu.Game.Online.Chat.Drawables { public class DrawableChannel : Container { - private readonly Channel channel; + public readonly Channel Channel; private readonly FillFlowContainer flow; private readonly ScrollContainer scroll; public DrawableChannel(Channel channel) { - this.channel = channel; + Channel = channel; RelativeSizeAxes = Axes.Both; Children = new Drawable[] { - new OsuSpriteText - { - Text = channel.Name, - TextSize = 50, - Alpha = 0.3f, - Anchor = Anchor.Centre, - Origin = Anchor.Centre - }, scroll = new ScrollContainer { RelativeSizeAxes = Axes.Both, @@ -56,14 +47,14 @@ namespace osu.Game.Online.Chat.Drawables { base.LoadComplete(); - newMessagesArrived(channel.Messages); + newMessagesArrived(Channel.Messages); scrollToEnd(); } protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - channel.NewMessagesArrived -= newMessagesArrived; + Channel.NewMessagesArrived -= newMessagesArrived; } private void newMessagesArrived(IEnumerable newMessages) @@ -93,4 +84,4 @@ namespace osu.Game.Online.Chat.Drawables private void scrollToEnd() => Scheduler.AddDelayed(() => scroll.ScrollToEnd(), 50); } -} \ No newline at end of file +} diff --git a/osu.Game/Overlays/ChatOverlay.cs b/osu.Game/Overlays/ChatOverlay.cs index dc586bd363..75ddcd89b6 100644 --- a/osu.Game/Overlays/ChatOverlay.cs +++ b/osu.Game/Overlays/ChatOverlay.cs @@ -30,9 +30,7 @@ namespace osu.Game.Overlays private ScheduledDelegate messageRequest; - private readonly Container content; - - protected override Container Content => content; + private readonly Container currentChannelContainer; private readonly FocusedTextBox inputTextBox; @@ -42,6 +40,8 @@ namespace osu.Game.Overlays private GetMessagesRequest fetchReq; + private readonly OsuTabControl channelTabs; + public ChatOverlay() { RelativeSizeAxes = Axes.X; @@ -49,8 +49,13 @@ namespace osu.Game.Overlays Anchor = Anchor.BottomLeft; Origin = Anchor.BottomLeft; - AddInternal(new Drawable[] + Children = new Drawable[] { + channelTabs = new OsuTabControl + { + RelativeSizeAxes = Axes.X, + Height = 20, + }, new Box { Depth = float.MaxValue, @@ -58,10 +63,10 @@ namespace osu.Game.Overlays Colour = Color4.Black, Alpha = 0.9f, }, - content = new Container + currentChannelContainer = new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = 5, Bottom = textbox_height + 5 }, + Padding = new MarginPadding { Top = 25, Bottom = textbox_height + 5 }, }, new Container { @@ -83,7 +88,9 @@ namespace osu.Game.Overlays } } } - }); + }; + + channelTabs.Current.ValueChanged += newChannel => CurrentChannel = newChannel; } public void APIStateChanged(APIAccess api, APIState state) @@ -135,9 +142,13 @@ namespace osu.Game.Overlays private List careChannels; + private readonly List loadedChannels = new List(); + private void initializeChannels() { - Clear(); + currentChannelContainer.Clear(); + + loadedChannels.Clear(); careChannels = new List(); @@ -160,25 +171,67 @@ namespace osu.Game.Overlays Scheduler.Add(delegate { loading.FadeOut(100); + addChannel(channels.Find(c => c.Name == @"#lazer")); + addChannel(channels.Find(c => c.Name == @"#osu")); + addChannel(channels.Find(c => c.Name == @"#lobby")); }); - messageRequest = Scheduler.AddDelayed(fetchNewMessages, 1000, true); + messageRequest = Scheduler.AddDelayed(() => fetchNewMessages(), 1000, true); }; + api.Queue(req); } + private Channel currentChannel; + + protected Channel CurrentChannel + { + get + { + return currentChannel; + } + + set + { + if (currentChannel == value) return; + + if (currentChannel != null) + currentChannelContainer.Clear(false); + + currentChannel = value; + + var loaded = loadedChannels.Find(d => d.Channel == value); + if (loaded == null) + loadedChannels.Add(loaded = new DrawableChannel(currentChannel)); + + inputTextBox.Current.Disabled = currentChannel.ReadOnly; + + currentChannelContainer.Add(loaded); + + channelTabs.Current.Value = value; + } + } + private void addChannel(Channel channel) { - Add(new DrawableChannel(channel)); + if (channel == null) return; + careChannels.Add(channel); + channelTabs.AddItem(channel); + + // we need to get a good number of messages initially for each channel we care about. + fetchNewMessages(channel); + + if (CurrentChannel == null) + CurrentChannel = channel; } - private void fetchNewMessages() + private void fetchNewMessages(Channel specificChannel = null) { if (fetchReq != null) return; - fetchReq = new GetMessagesRequest(careChannels, lastMessageId); + fetchReq = new GetMessagesRequest(specificChannel != null ? new List { specificChannel } : careChannels, lastMessageId); fetchReq.Success += delegate (List messages) { var ids = messages.Where(m => m.TargetType == TargetType.Channel).Select(m => m.TargetId).Distinct(); @@ -207,8 +260,6 @@ namespace osu.Game.Overlays if (!string.IsNullOrEmpty(postText) && api.LocalUser.Value != null) { - var currentChannel = careChannels.FirstOrDefault(); - if (currentChannel == null) return; var message = new Message