diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 87d1b1a3ad..e7b349b313 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -42,7 +42,9 @@ namespace osu.Game.Overlays.Chat protected virtual float TextSize => 20; - private Color4 customUsernameColour; + private Container lineBackground; + + private Color4 usernameColour; private OsuSpriteText timestamp; @@ -78,19 +80,22 @@ namespace osu.Game.Overlays.Chat } } - private bool senderHasBackground => !string.IsNullOrEmpty(message.Sender.Colour); + private bool senderHasColour => !string.IsNullOrEmpty(message.Sender.Colour); + + [Resolved] + private OsuColour colours { get; set; } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { - customUsernameColour = colours.ChatBlue; - - bool hasBackground = senderHasBackground; + usernameColour = senderHasColour + ? Color4Extensions.FromHex(message.Sender.Colour) + : username_colours[message.Sender.Id % username_colours.Length]; Drawable effectedUsername = username = new OsuSpriteText { Shadow = false, - Colour = hasBackground ? customUsernameColour : username_colours[message.Sender.Id % username_colours.Length], + Colour = senderHasColour ? colours.ChatBlue : usernameColour, Truncate = true, EllipsisString = "… :", Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true), @@ -99,7 +104,7 @@ namespace osu.Game.Overlays.Chat MaxWidth = MessagePadding - TimestampPadding }; - if (hasBackground) + if (senderHasColour) { // Background effect effectedUsername = new Container @@ -126,7 +131,7 @@ namespace osu.Game.Overlays.Chat new Box { RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(message.Sender.Colour), + Colour = usernameColour, }, new Container { @@ -141,6 +146,14 @@ namespace osu.Game.Overlays.Chat InternalChildren = new Drawable[] { + lineBackground = new Container + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.0f), + CornerRadius = 2f, + Masking = true, + Child = new Box { RelativeSizeAxes = Axes.Both } + }, new Container { Size = new Vector2(MessagePadding, TextSize), @@ -177,7 +190,7 @@ namespace osu.Game.Overlays.Chat { t.Font = OsuFont.GetFont(italics: true); - if (senderHasBackground) + if (senderHasColour) t.Colour = Color4Extensions.FromHex(message.Sender.Colour); } @@ -200,13 +213,21 @@ namespace osu.Game.Overlays.Chat FinishTransforms(true); } + /// + /// Schedules a message highlight animation. + /// + /// + /// Scheduling is required to ensure the animation doesn't play until the chat line is in view and not scrolled away. + /// + public void ScheduleHighlight() => Schedule(() => lineBackground.FlashColour(usernameColour.Darken(1f).Opacity(0.5f), 1000, Easing.InQuint)); + private void updateMessageContent() { this.FadeTo(message is LocalEchoMessage ? 0.4f : 1.0f, 500, Easing.OutQuint); timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint); timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}"; - username.Text = $@"{message.Sender.Username}" + (senderHasBackground || message.IsAction ? "" : ":"); + username.Text = $@"{message.Sender.Username}" + (senderHasColour || message.IsAction ? "" : ":"); // remove non-existent channels from the link list message.Links.RemoveAll(link => link.Action == LinkAction.OpenChannel && chatManager?.AvailableChannels.Any(c => c.Name == link.Argument.ToString()) != true); diff --git a/osu.Game/Overlays/Chat/DrawableChannel.cs b/osu.Game/Overlays/Chat/DrawableChannel.cs index 6220beeb82..cca089873f 100644 --- a/osu.Game/Overlays/Chat/DrawableChannel.cs +++ b/osu.Game/Overlays/Chat/DrawableChannel.cs @@ -79,6 +79,28 @@ namespace osu.Game.Overlays.Chat Channel.PendingMessageResolved += pendingMessageResolved; } + /// + /// Highlights a specific message in this drawable channel. + /// + /// The message to highlight. + public void HighlightMessage(Message message) + { + if (IsLoaded) + highlightMessage(message); + else + Schedule(highlightMessage, message); + } + + private void highlightMessage(Message message) + { + var chatLine = chatLines.SingleOrDefault(c => c.Message == message); + if (chatLine == null) + return; + + scroll.ScrollIntoView(chatLine); + chatLine.ScheduleHighlight(); + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing);