mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 21:07:33 +08:00
Merge branch 'master' into auto-restart
This commit is contained in:
commit
989d337532
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -19,6 +20,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
{
|
{
|
||||||
private ChannelManager channelManager;
|
private ChannelManager channelManager;
|
||||||
private int currentMessageId;
|
private int currentMessageId;
|
||||||
|
private List<Message> sentMessages;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
@ -34,6 +36,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
AddStep("register request handling", () =>
|
AddStep("register request handling", () =>
|
||||||
{
|
{
|
||||||
currentMessageId = 0;
|
currentMessageId = 0;
|
||||||
|
sentMessages = new List<Message>();
|
||||||
|
|
||||||
((DummyAPIAccess)API).HandleRequest = req =>
|
((DummyAPIAccess)API).HandleRequest = req =>
|
||||||
{
|
{
|
||||||
@ -44,16 +47,11 @@ namespace osu.Game.Tests.Chat
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case PostMessageRequest postMessage:
|
case PostMessageRequest postMessage:
|
||||||
postMessage.TriggerSuccess(new Message(++currentMessageId)
|
handlePostMessageRequest(postMessage);
|
||||||
{
|
return true;
|
||||||
IsAction = postMessage.Message.IsAction,
|
|
||||||
ChannelId = postMessage.Message.ChannelId,
|
|
||||||
Content = postMessage.Message.Content,
|
|
||||||
Links = postMessage.Message.Links,
|
|
||||||
Timestamp = postMessage.Message.Timestamp,
|
|
||||||
Sender = postMessage.Message.Sender
|
|
||||||
});
|
|
||||||
|
|
||||||
|
case MarkChannelAsReadRequest markRead:
|
||||||
|
handleMarkChannelAsReadRequest(markRead);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,12 +81,65 @@ namespace osu.Game.Tests.Chat
|
|||||||
AddAssert("/np command received by channel 2", () => channel2.Messages.Last().Content.Contains("is listening to"));
|
AddAssert("/np command received by channel 2", () => channel2.Messages.Last().Content.Contains("is listening to"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMarkAsReadIgnoringLocalMessages()
|
||||||
|
{
|
||||||
|
Channel channel = null;
|
||||||
|
|
||||||
|
AddStep("join channel and select it", () =>
|
||||||
|
{
|
||||||
|
channelManager.JoinChannel(channel = createChannel(1, ChannelType.Public));
|
||||||
|
channelManager.CurrentChannel.Value = channel;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("post message", () => channelManager.PostMessage("Something interesting"));
|
||||||
|
|
||||||
|
AddStep("post /help command", () => channelManager.PostCommand("help", channel));
|
||||||
|
AddStep("post /me command with no action", () => channelManager.PostCommand("me", channel));
|
||||||
|
AddStep("post /join command with no channel", () => channelManager.PostCommand("join", channel));
|
||||||
|
AddStep("post /join command with non-existent channel", () => channelManager.PostCommand("join i-dont-exist", channel));
|
||||||
|
AddStep("post non-existent command", () => channelManager.PostCommand("non-existent-cmd arg", channel));
|
||||||
|
|
||||||
|
AddStep("mark channel as read", () => channelManager.MarkChannelAsRead(channel));
|
||||||
|
AddAssert("channel's last read ID is set to the latest message", () => channel.LastReadId == sentMessages.Last().Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePostMessageRequest(PostMessageRequest request)
|
||||||
|
{
|
||||||
|
var message = new Message(++currentMessageId)
|
||||||
|
{
|
||||||
|
IsAction = request.Message.IsAction,
|
||||||
|
ChannelId = request.Message.ChannelId,
|
||||||
|
Content = request.Message.Content,
|
||||||
|
Links = request.Message.Links,
|
||||||
|
Timestamp = request.Message.Timestamp,
|
||||||
|
Sender = request.Message.Sender
|
||||||
|
};
|
||||||
|
|
||||||
|
sentMessages.Add(message);
|
||||||
|
request.TriggerSuccess(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleMarkChannelAsReadRequest(MarkChannelAsReadRequest request)
|
||||||
|
{
|
||||||
|
// only accept messages that were sent through the API
|
||||||
|
if (sentMessages.Contains(request.Message))
|
||||||
|
{
|
||||||
|
request.TriggerSuccess();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
request.TriggerFailure(new APIException("unknown message!", null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Channel createChannel(int id, ChannelType type) => new Channel(new User())
|
private Channel createChannel(int id, ChannelType type) => new Channel(new User())
|
||||||
{
|
{
|
||||||
Id = id,
|
Id = id,
|
||||||
Name = $"Channel {id}",
|
Name = $"Channel {id}",
|
||||||
Topic = $"Topic of channel {id} with type {type}",
|
Topic = $"Topic of channel {id} with type {type}",
|
||||||
Type = type,
|
Type = type,
|
||||||
|
LastMessageId = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
private class ChannelManagerContainer : CompositeDrawable
|
private class ChannelManagerContainer : CompositeDrawable
|
||||||
|
@ -9,16 +9,16 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
public class MarkChannelAsReadRequest : APIRequest
|
public class MarkChannelAsReadRequest : APIRequest
|
||||||
{
|
{
|
||||||
private readonly Channel channel;
|
public readonly Channel Channel;
|
||||||
private readonly Message message;
|
public readonly Message Message;
|
||||||
|
|
||||||
public MarkChannelAsReadRequest(Channel channel, Message message)
|
public MarkChannelAsReadRequest(Channel channel, Message message)
|
||||||
{
|
{
|
||||||
this.channel = channel;
|
Channel = channel;
|
||||||
this.message = message;
|
Message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string Target => $"chat/channels/{channel.Id}/mark-as-read/{message.Id}";
|
protected override string Target => $"chat/channels/{Channel.Id}/mark-as-read/{Message.Id}";
|
||||||
|
|
||||||
protected override WebRequest CreateWebRequest()
|
protected override WebRequest CreateWebRequest()
|
||||||
{
|
{
|
||||||
|
@ -553,7 +553,7 @@ namespace osu.Game.Online.Chat
|
|||||||
if (channel.LastMessageId == channel.LastReadId)
|
if (channel.LastMessageId == channel.LastReadId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var message = channel.Messages.LastOrDefault();
|
var message = channel.Messages.FindLast(msg => !(msg is LocalMessage));
|
||||||
|
|
||||||
if (message == null)
|
if (message == null)
|
||||||
return;
|
return;
|
||||||
|
@ -78,10 +78,10 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
Direction = FillDirection.Horizontal,
|
Direction = FillDirection.Horizontal,
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
length = new Statistic(FontAwesome.Regular.Clock, "Length") { Width = 0.25f },
|
length = new Statistic(BeatmapStatisticsIconType.Length, "Length") { Width = 0.25f },
|
||||||
bpm = new Statistic(FontAwesome.Regular.Circle, "BPM") { Width = 0.25f },
|
bpm = new Statistic(BeatmapStatisticsIconType.Bpm, "BPM") { Width = 0.25f },
|
||||||
circleCount = new Statistic(FontAwesome.Regular.Circle, "Circle Count") { Width = 0.25f },
|
circleCount = new Statistic(BeatmapStatisticsIconType.Circles, "Circle Count") { Width = 0.25f },
|
||||||
sliderCount = new Statistic(FontAwesome.Regular.Circle, "Slider Count") { Width = 0.25f },
|
sliderCount = new Statistic(BeatmapStatisticsIconType.Sliders, "Slider Count") { Width = 0.25f },
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -104,7 +104,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
set => this.value.Text = value;
|
set => this.value.Text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Statistic(IconUsage icon, string name)
|
public Statistic(BeatmapStatisticsIconType icon, string name)
|
||||||
{
|
{
|
||||||
TooltipText = name;
|
TooltipText = name;
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
@ -133,8 +133,16 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Icon = icon,
|
Icon = FontAwesome.Regular.Circle,
|
||||||
Size = new Vector2(12),
|
Size = new Vector2(10),
|
||||||
|
Rotation = 0,
|
||||||
|
Colour = Color4Extensions.FromHex(@"f7dd55"),
|
||||||
|
},
|
||||||
|
new BeatmapStatisticIcon(icon)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.CentreLeft,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(10),
|
||||||
Colour = Color4Extensions.FromHex(@"f7dd55"),
|
Colour = Color4Extensions.FromHex(@"f7dd55"),
|
||||||
Scale = new Vector2(0.8f),
|
Scale = new Vector2(0.8f),
|
||||||
},
|
},
|
||||||
|
@ -10,12 +10,12 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
|||||||
{
|
{
|
||||||
public class OnlinePlayBackgroundSprite : OnlinePlayComposite
|
public class OnlinePlayBackgroundSprite : OnlinePlayComposite
|
||||||
{
|
{
|
||||||
private readonly BeatmapSetCoverType beatmapSetCoverType;
|
protected readonly BeatmapSetCoverType BeatmapSetCoverType;
|
||||||
private UpdateableBeatmapBackgroundSprite sprite;
|
private UpdateableBeatmapBackgroundSprite sprite;
|
||||||
|
|
||||||
public OnlinePlayBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover)
|
public OnlinePlayBackgroundSprite(BeatmapSetCoverType beatmapSetCoverType = BeatmapSetCoverType.Cover)
|
||||||
{
|
{
|
||||||
this.beatmapSetCoverType = beatmapSetCoverType;
|
BeatmapSetCoverType = beatmapSetCoverType;
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -33,6 +33,6 @@ namespace osu.Game.Screens.OnlinePlay.Components
|
|||||||
sprite.Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap.Value;
|
sprite.Beatmap.Value = Playlist.FirstOrDefault()?.Beatmap.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(beatmapSetCoverType) { RelativeSizeAxes = Axes.Both };
|
protected virtual UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new UpdateableBeatmapBackgroundSprite(BeatmapSetCoverType) { RelativeSizeAxes = Axes.Both };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -158,11 +158,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
|||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
// This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites.
|
// This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites.
|
||||||
new BufferedContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
@ -172,8 +167,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both
|
RelativeSizeAxes = Axes.Both
|
||||||
},
|
},
|
||||||
}
|
|
||||||
},
|
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
Name = @"Room content",
|
Name = @"Room content",
|
||||||
@ -186,12 +179,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
|||||||
Masking = true,
|
Masking = true,
|
||||||
CornerRadius = corner_radius,
|
CornerRadius = corner_radius,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
|
||||||
// This resolves internal 1px gaps due to applying the (parenting) corner radius and masking across multiple filling background sprites.
|
|
||||||
new BufferedContainer
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
{
|
||||||
new GridContainer
|
new GridContainer
|
||||||
{
|
{
|
||||||
@ -217,8 +204,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
|
||||||
},
|
|
||||||
new Container
|
new Container
|
||||||
{
|
{
|
||||||
Name = @"Left details",
|
Name = @"Left details",
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Drawables;
|
using osu.Game.Beatmaps.Drawables;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Input;
|
using osu.Game.Input;
|
||||||
@ -104,14 +105,9 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new BufferedContainer
|
new BeatmapBackgroundSprite
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
BlurSigma = new Vector2(10),
|
|
||||||
Child = new BeatmapBackgroundSprite
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both
|
RelativeSizeAxes = Axes.Both
|
||||||
}
|
|
||||||
},
|
},
|
||||||
new Box
|
new Box
|
||||||
{
|
{
|
||||||
@ -306,11 +302,46 @@ namespace osu.Game.Screens.OnlinePlay
|
|||||||
|
|
||||||
private class BeatmapBackgroundSprite : OnlinePlayBackgroundSprite
|
private class BeatmapBackgroundSprite : OnlinePlayBackgroundSprite
|
||||||
{
|
{
|
||||||
protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both };
|
protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BlurredBackgroundSprite(BeatmapSetCoverType) { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
private class BackgroundSprite : UpdateableBeatmapBackgroundSprite
|
public class BlurredBackgroundSprite : UpdateableBeatmapBackgroundSprite
|
||||||
{
|
{
|
||||||
|
public BlurredBackgroundSprite(BeatmapSetCoverType type)
|
||||||
|
: base(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected override double LoadDelay => 200;
|
protected override double LoadDelay => 200;
|
||||||
|
|
||||||
|
protected override Drawable CreateDrawable(BeatmapInfo model) =>
|
||||||
|
new BufferedLoader(base.CreateDrawable(model));
|
||||||
|
}
|
||||||
|
|
||||||
|
// This class is an unfortunate requirement due to `LongRunningLoad` requiring direct async loading.
|
||||||
|
// It means that if the web request fetching the beatmap background takes too long, it will suddenly appear.
|
||||||
|
internal class BufferedLoader : BufferedContainer
|
||||||
|
{
|
||||||
|
private readonly Drawable drawable;
|
||||||
|
|
||||||
|
public BufferedLoader(Drawable drawable)
|
||||||
|
{
|
||||||
|
this.drawable = drawable;
|
||||||
|
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
BlurSigma = new Vector2(10);
|
||||||
|
FrameBufferScale = new Vector2(0.5f);
|
||||||
|
CacheDrawnFrameBuffer = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
LoadComponentAsync(drawable, d =>
|
||||||
|
{
|
||||||
|
Add(d);
|
||||||
|
ForceRedraw();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user