1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 11:42:56 +08:00

Merge pull request #18610 from jai-x/refactor-chat-line

Refactor `ChatLine` and fix `DrawableChannel` flow padding
This commit is contained in:
Dean Herbert 2022-06-08 13:54:53 +09:00 committed by GitHub
commit eee79c9531
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 114 additions and 158 deletions

View File

@ -572,15 +572,15 @@ namespace osu.Game.Tests.Visual.Online
public SlowLoadingDrawableChannel GetSlowLoadingChannel(Channel channel) => DrawableChannels.OfType<SlowLoadingDrawableChannel>().Single(c => c.Channel == channel);
protected override ChatOverlayDrawableChannel CreateDrawableChannel(Channel newChannel)
protected override DrawableChannel CreateDrawableChannel(Channel newChannel)
{
return SlowLoading
? new SlowLoadingDrawableChannel(newChannel)
: new ChatOverlayDrawableChannel(newChannel);
: new DrawableChannel(newChannel);
}
}
private class SlowLoadingDrawableChannel : ChatOverlayDrawableChannel
private class SlowLoadingDrawableChannel : DrawableChannel
{
public readonly ManualResetEventSlim LoadEvent = new ManualResetEventSlim();

View File

@ -160,13 +160,6 @@ namespace osu.Game.Online.Chat
{
}
[BackgroundDependencyLoader]
private void load()
{
// TODO: Remove once DrawableChannel & ChatLine padding is fixed
ChatLineFlow.Padding = new MarginPadding { Horizontal = 0 };
}
protected override ChatLine CreateChatLine(Message m) => CreateChatLineAction(m);
protected override DaySeparator CreateDaySeparator(DateTimeOffset time) => new StandAloneDaySeparator(time);
@ -176,8 +169,8 @@ namespace osu.Game.Online.Chat
{
protected override float TextSize => 14;
protected override float LineHeight => 1;
protected override float Spacing => 10;
protected override float DateAlign => 120;
protected override float Spacing => 5;
protected override float DateAlign => 125;
public StandAloneDaySeparator(DateTimeOffset time)
: base(time)
@ -189,17 +182,15 @@ namespace osu.Game.Online.Chat
{
Height = 25;
Colour = colours.Yellow;
// TODO: Remove once DrawableChannel & ChatLine padding is fixed
Padding = new MarginPadding { Horizontal = 10 };
}
}
protected class StandAloneMessage : ChatLine
{
protected override float TextSize => 15;
protected override float HorizontalPadding => 10;
protected override float MessagePadding => 120;
protected override float TimestampPadding => 50;
protected override float Spacing => 5;
protected override float TimestampWidth => 45;
protected override float UsernameWidth => 75;
public StandAloneMessage(Message message)
: base(message)

View File

@ -26,22 +26,14 @@ namespace osu.Game.Overlays.Chat
{
public class ChatLine : CompositeDrawable
{
public const float LEFT_PADDING = default_message_padding + default_horizontal_padding * 2;
private const float default_message_padding = 200;
protected virtual float MessagePadding => default_message_padding;
private const float default_timestamp_padding = 65;
protected virtual float TimestampPadding => default_timestamp_padding;
private const float default_horizontal_padding = 15;
protected virtual float HorizontalPadding => default_horizontal_padding;
protected virtual float TextSize => 20;
protected virtual float Spacing => 15;
protected virtual float TimestampWidth => 60;
protected virtual float UsernameWidth => 130;
private Color4 usernameColour;
private OsuSpriteText timestamp;
@ -49,7 +41,6 @@ namespace osu.Game.Overlays.Chat
public ChatLine(Message message)
{
Message = message;
Padding = new MarginPadding { Left = HorizontalPadding, Right = HorizontalPadding };
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
}
@ -90,88 +81,45 @@ namespace osu.Game.Overlays.Chat
? Color4Extensions.FromHex(message.Sender.Colour)
: username_colours[message.Sender.Id % username_colours.Length];
Drawable effectedUsername = username = new OsuSpriteText
InternalChild = new GridContainer
{
Shadow = false,
Colour = senderHasColour ? colours.ChatBlue : usernameColour,
Truncate = true,
EllipsisString = "… :",
Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true),
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
MaxWidth = MessagePadding - TimestampPadding
};
if (senderHasColour)
{
// Background effect
effectedUsername = new Container
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
ColumnDimensions = new[]
{
AutoSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 4,
EdgeEffect = new EdgeEffectParameters
{
Roundness = 1,
Radius = 1,
Colour = Color4.Black.Opacity(0.3f),
Offset = new Vector2(0, 1),
Type = EdgeEffectType.Shadow,
},
Child = new Container
{
AutoSizeAxes = Axes.Both,
Y = 0,
Masking = true,
CornerRadius = 4,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = usernameColour,
},
new Container
{
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 },
Child = username
}
}
}
};
}
InternalChildren = new Drawable[]
{
new Container
{
Size = new Vector2(MessagePadding, TextSize),
Children = new Drawable[]
{
timestamp = new OsuSpriteText
{
Shadow = false,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true)
},
new MessageSender(message.Sender)
{
AutoSizeAxes = Axes.Both,
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
Child = effectedUsername,
},
}
new Dimension(GridSizeMode.Absolute, TimestampWidth + Spacing + UsernameWidth + Spacing),
new Dimension(),
},
new Container
Content = new[]
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Left = MessagePadding + HorizontalPadding },
Children = new Drawable[]
new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Children = new Drawable[]
{
timestamp = new OsuSpriteText
{
Shadow = false,
Anchor = Anchor.CentreLeft,
Origin = Anchor.CentreLeft,
Font = OsuFont.GetFont(size: TextSize * 0.75f, weight: FontWeight.SemiBold, fixedWidth: true),
MaxWidth = TimestampWidth,
},
new MessageSender(message.Sender)
{
Width = UsernameWidth,
AutoSizeAxes = Axes.Y,
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
Child = createUsername(),
Margin = new MarginPadding { Horizontal = Spacing },
},
},
},
ContentFlow = new LinkFlowContainer(t =>
{
t.Shadow = false;
@ -190,7 +138,7 @@ namespace osu.Game.Overlays.Chat
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
}
}
},
}
};
}
@ -233,7 +181,7 @@ namespace osu.Game.Overlays.Chat
timestamp.FadeTo(message is LocalEchoMessage ? 0 : 1, 500, Easing.OutQuint);
timestamp.Text = $@"{message.Timestamp.LocalDateTime:HH:mm:ss}";
username.Text = $@"{message.Sender.Username}" + (senderHasColour || message.IsAction ? "" : ":");
username.Text = $@"{message.Sender.Username}";
// 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);
@ -242,6 +190,62 @@ namespace osu.Game.Overlays.Chat
ContentFlow.AddLinks(message.DisplayContent, message.Links);
}
private Drawable createUsername()
{
username = new OsuSpriteText
{
Shadow = false,
Colour = senderHasColour ? colours.ChatBlue : usernameColour,
Truncate = true,
EllipsisString = "…",
Font = OsuFont.GetFont(size: TextSize, weight: FontWeight.Bold, italics: true),
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
MaxWidth = UsernameWidth,
};
if (!senderHasColour)
return username;
// Background effect
return new Container
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
AutoSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 4,
EdgeEffect = new EdgeEffectParameters
{
Roundness = 1,
Radius = 1,
Colour = Color4.Black.Opacity(0.3f),
Offset = new Vector2(0, 1),
Type = EdgeEffectType.Shadow,
},
Child = new Container
{
AutoSizeAxes = Axes.Both,
Masking = true,
CornerRadius = 4,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = usernameColour,
},
new Container
{
AutoSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = 4, Right = 4, Bottom = 1, Top = -2 },
Child = username
}
}
}
};
}
private class MessageSender : OsuClickableContainer, IHasContextMenu
{
private readonly APIUser sender;

View File

@ -1,39 +0,0 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
#nullable enable
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Online.Chat;
namespace osu.Game.Overlays.Chat
{
public class ChatOverlayDrawableChannel : DrawableChannel
{
public ChatOverlayDrawableChannel(Channel channel)
: base(channel)
{
}
[BackgroundDependencyLoader]
private void load()
{
// TODO: Remove once DrawableChannel & ChatLine padding is fixed
ChatLineFlow.Padding = new MarginPadding(0);
}
protected override DaySeparator CreateDaySeparator(DateTimeOffset time) => new ChatOverlayDaySeparator(time);
private class ChatOverlayDaySeparator : DaySeparator
{
public ChatOverlayDaySeparator(DateTimeOffset time)
: base(time)
{
// TODO: Remove once DrawableChannel & ChatLine padding is fixed
Padding = new MarginPadding { Horizontal = 15 };
}
}
}
}

View File

@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Chat
protected virtual float LineHeight => 2;
protected virtual float DateAlign => 200;
protected virtual float DateAlign => 205;
protected virtual float Spacing => 15;

View File

@ -59,7 +59,7 @@ namespace osu.Game.Overlays.Chat
Padding = new MarginPadding { Bottom = 5 },
Child = ChatLineFlow = new FillFlowContainer
{
Padding = new MarginPadding { Horizontal = 15 },
Padding = new MarginPadding { Horizontal = 10 },
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,

View File

@ -38,9 +38,9 @@ namespace osu.Game.Overlays
private LoadingLayer loading = null!;
private ChannelListing channelListing = null!;
private ChatTextBar textBar = null!;
private Container<ChatOverlayDrawableChannel> currentChannelContainer = null!;
private Container<DrawableChannel> currentChannelContainer = null!;
private readonly Dictionary<Channel, ChatOverlayDrawableChannel> loadedChannels = new Dictionary<Channel, ChatOverlayDrawableChannel>();
private readonly Dictionary<Channel, DrawableChannel> loadedChannels = new Dictionary<Channel, DrawableChannel>();
protected IEnumerable<DrawableChannel> DrawableChannels => loadedChannels.Values;
@ -126,7 +126,7 @@ namespace osu.Game.Overlays
RelativeSizeAxes = Axes.Both,
Colour = colourProvider.Background4,
},
currentChannelContainer = new Container<ChatOverlayDrawableChannel>
currentChannelContainer = new Container<DrawableChannel>
{
RelativeSizeAxes = Axes.Both,
},
@ -313,7 +313,7 @@ namespace osu.Game.Overlays
loading.Show();
// Ensure the drawable channel is stored before async load to prevent double loading
ChatOverlayDrawableChannel drawableChannel = CreateDrawableChannel(newChannel);
DrawableChannel drawableChannel = CreateDrawableChannel(newChannel);
loadedChannels.Add(newChannel, drawableChannel);
LoadComponentAsync(drawableChannel, loadedDrawable =>
@ -338,7 +338,7 @@ namespace osu.Game.Overlays
channelManager.MarkChannelAsRead(newChannel);
}
protected virtual ChatOverlayDrawableChannel CreateDrawableChannel(Channel newChannel) => new ChatOverlayDrawableChannel(newChannel);
protected virtual DrawableChannel CreateDrawableChannel(Channel newChannel) => new DrawableChannel(newChannel);
private void joinedChannelsChanged(object sender, NotifyCollectionChangedEventArgs args)
{
@ -361,7 +361,7 @@ namespace osu.Game.Overlays
if (loadedChannels.ContainsKey(channel))
{
ChatOverlayDrawableChannel loaded = loadedChannels[channel];
DrawableChannel loaded = loadedChannels[channel];
loadedChannels.Remove(channel);
// DrawableChannel removed from cache must be manually disposed
loaded.Dispose();