1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 08:13:31 +08:00
This commit is contained in:
HoutarouOreki 2018-07-19 19:07:24 +02:00
parent 11e0732a27
commit bcd132e87f
14 changed files with 399 additions and 82 deletions

View File

@ -10,9 +10,9 @@ namespace osu.Game.Tests.Visual
public class TestCaseChangelog : OsuTestCase
{
private ChangelogOverlay changelog;
private int releaseStreamCount;
private int index;
private void indexIncrement() => index = index == releaseStreamCount - 1 ? 0 : index + 1;
private void indexIncrement() => index = index >= changelog.Streams.BadgesContainer.Children.Count - 1 ? 0 : index + 1;
private bool isLoaded => changelog.Streams.BadgesContainer.Children.Count > 0;
protected override void LoadComplete()
{
@ -20,20 +20,18 @@ namespace osu.Game.Tests.Visual
Add(changelog = new ChangelogOverlay());
releaseStreamCount = changelog.Streams.BadgesContainer.Children.Count;
AddStep(@"Show", changelog.Show);
AddRepeatStep(@"Toggle Release Stream", () =>
{
changelog.Streams.BadgesContainer.Children[index].Activate();
if (isLoaded) changelog.Streams.BadgesContainer.Children[index].Activate();
indexIncrement();
}, releaseStreamCount);
}, 6);
AddStep(@"Listing", changelog.ActivateListing);
AddStep(@"Hide", changelog.Hide);
AddWaitStep(3);
AddStep(@"Show with Release Stream", () =>
{
changelog.Streams.BadgesContainer.Children[index].Activate();
if (isLoaded) changelog.Streams.BadgesContainer.Children[index].Activate();
changelog.Show();
indexIncrement();
});
@ -45,12 +43,12 @@ namespace osu.Game.Tests.Visual
changelog.ActivateListing();
changelog.Show();
});
AddWaitStep(4);
AddWaitStep(3);
AddStep(@"Hide", changelog.Hide);
AddWaitStep(3);
AddStep(@"Activate release", () =>
{
changelog.Streams.BadgesContainer.Children[index].Activate();
if (isLoaded) changelog.Streams.BadgesContainer.Children[index].Activate();
indexIncrement();
});
AddStep(@"Show with listing", () =>

View File

@ -2,6 +2,8 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Graphics;
using osu.Framework.Graphics.Colour;
using System.Collections.Generic;
namespace osu.Game.Graphics
{
@ -13,5 +15,22 @@ namespace osu.Game.Graphics
public static readonly Color4 CUTTINGEDGE = new Color4(238, 170, 0, 255);
public static readonly Color4 LAZER = new Color4(237, 18, 33, 255);
public static readonly Color4 WEB = new Color4(136, 102, 238, 255);
private static readonly Dictionary<string, ColourInfo> colours = new Dictionary<string, ColourInfo>
{
{ "stable40", STABLE },
{ "stable", STABLEFALLBACK },
{ "beta40", BETA },
{ "cuttingedge", CUTTINGEDGE },
{ "lazer", LAZER },
{ "web", WEB },
};
public static ColourInfo FromStreamName(string name)
{
if (colours.TryGetValue(name, out ColourInfo colour))
return colour;
else return new Color4(255, 255, 255, 255);
}
}
}

View File

@ -0,0 +1,43 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.Containers;
namespace osu.Game.Graphics.UserInterface
{
public class TooltipIconButton : OsuClickableContainer, IHasTooltip
{
private readonly SpriteIcon icon;
public FontAwesome Icon
{
get { return icon.Icon; }
set { icon.Icon = value; }
}
public TooltipIconButton()
{
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Alpha = 0,
},
icon = new SpriteIcon
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Size = new Vector2(18),
}
};
}
public string TooltipText { get; set; }
}
}

View File

@ -0,0 +1,17 @@
// 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.Game.Online.API.Requests.Responses;
using System.Collections.Generic;
namespace osu.Game.Online.API.Requests
{
/// <summary>
/// Obviously a placeholder
/// </summary>
public class GetChangelogLatestBuildsRequest : APIRequest<List<APIChangelog>>
{
protected override string Uri => Target;
protected override string Target => @"https://api.myjson.com/bins/16waui";
}
}

View File

@ -0,0 +1,13 @@
// 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.Game.Online.API.Requests.Responses;
namespace osu.Game.Online.API.Requests
{
public class GetChangelogRequest : APIRequest<APIChangelog[]>
{
protected override string Uri => Target;
protected override string Target => "https://api.myjson.com/bins/6zv2i";
}
}

View File

@ -0,0 +1,54 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace osu.Game.Online.API.Requests.Responses
{
public class APIChangelog
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("version")]
public string Version { get; set; }
[JsonProperty("display_version")]
public string DisplayVersion { get; set; }
[JsonProperty("users")]
public long Users { get; set; }
[JsonProperty("is_featured")]
public bool IsFeatured { get; set; }
[JsonProperty("created_at")]
public DateTimeOffset CreatedAt { get; set; }
[JsonProperty("disqus_id")]
public string DisqusId { get; set; }
[JsonProperty("disqus_title")]
public string DisqusTitle { get; set; }
[JsonProperty("update_stream")]
public UpdateStream UpdateStream { get; set; }
[JsonProperty("changelog_entries")]
public List<object> ChangelogEntries { get; set; }
}
public class UpdateStream
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("display_name")]
public string DisplayName { get; set; }
}
}

View File

@ -0,0 +1,36 @@
// 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.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
namespace osu.Game.Overlays.Changelog
{
// maybe look to osu.Game.Screens.Play.SquareGraph for reference later
public class ChangelogChart : BufferedContainer
{
public ChangelogChart()
{
RelativeSizeAxes = Axes.X;
Height = 100;
Children = new Drawable[]
{
new Box
{
Colour = StreamColour.STABLE,
RelativeSizeAxes = Axes.Both,
},
new SpriteText
{
Text = "Graph Placeholder",
TextSize = 28,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
};
}
}
}

View File

@ -0,0 +1,18 @@
// 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.Graphics.Containers;
namespace osu.Game.Overlays.Changelog
{
public class ChangelogContent : FillFlowContainer<ChangelogContentGroup>
{
public ChangelogContent()
{
RelativeSizeAxes = Axes.X;
//AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
}
}
}

View File

@ -0,0 +1,109 @@
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API.Requests.Responses;
namespace osu.Game.Overlays.Changelog
{
public class ChangelogContentGroup : FillFlowContainer
{
// will porobably depend in some way on #1692 (https://github.com/ppy/osu-framework/pull/1692)
// need to keep in mind it looks different on Listing (one contains all builds from a date)
// and when a stream is selected (looks like now)
public ChangelogContentGroup(APIChangelog build)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
Direction = FillDirection.Vertical;
Padding = new MarginPadding
{
Left = 70,
Right = 70,
};
Children = new Drawable[]
{
// build version, arrows
new FillFlowContainer
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
AutoSizeAxes = Axes.Both,
Direction = FillDirection.Horizontal,
Margin = new MarginPadding
{
Top = 20,
},
Children = new Drawable[]
{
new TooltipIconButton
{
Icon = FontAwesome.fa_chevron_left,
Size = new Vector2(24),
// how do we link to previous/next builds?
// I'm thinking some linked list, but how do we make that
// from the available API data
TooltipText = "Previous",
},
new FillFlowContainer<SpriteText>
{
AutoSizeAxes = Axes.Both,
Margin = new MarginPadding
{
Left = 40,
Right = 40,
},
Children = new[]
{
new SpriteText
{
Text = build.UpdateStream.DisplayName,
TextSize = 28, // web: 24,
Font = @"Exo2.0-Medium",
},
new SpriteText // a space...
{
Text = " ",
TextSize = 28,
},
new SpriteText
{
Text = build.DisplayVersion,
TextSize = 28, // web: 24,
Colour = StreamColour.STABLE,
},
}
},
new TooltipIconButton
{
Icon = FontAwesome.fa_chevron_right,
Size = new Vector2(24),
TooltipText = "Next",
},
}
},
new SpriteText
{
// do we need .ToUniversalTime() here?
// also, this is a temporary solution to weekdays in >localized< date strings
Text = build.CreatedAt.Date.ToLongDateString().Replace(build.CreatedAt.ToString("dddd") + ", ", ""),
TextSize = 17, // web: 14,
Colour = OsuColour.FromHex(@"FD5"),
Font = @"Exo2.0-Medium",
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Margin = new MarginPadding
{
Top = 5,
},
},
};
}
//public ChangelogContentGroup(DateTimeOffset date) { }
}
}

View File

@ -11,6 +11,7 @@ using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Changelog.Header;
using System;
@ -27,6 +28,8 @@ namespace osu.Game.Overlays.Changelog
public Action OnListingActivated;
public APIChangelog ChangelogEntry;
private const float cover_height = 310;
private const float title_height = 50;
private const float icon_size = 50;
@ -181,10 +184,11 @@ namespace osu.Game.Overlays.Changelog
};
}
public void ShowReleaseStream(string headerText, string breadcrumbText)
public void ShowReleaseStream()
{
releaseStream.Activate(breadcrumbText);
changeHeaderText(headerText);
releaseStream.Activate(String.Join(" ",
ChangelogEntry.UpdateStream.DisplayName, ChangelogEntry.DisplayVersion));
changeHeaderText(ChangelogEntry.UpdateStream.DisplayName);
}
private void changeHeaderText(string headerText)

View File

@ -2,13 +2,12 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using OpenTK.Graphics;
using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Overlays.Changelog.Streams;
using osu.Game.Online.API.Requests.Responses;
using System;
namespace osu.Game.Overlays.Changelog
{
@ -17,8 +16,9 @@ namespace osu.Game.Overlays.Changelog
private const float container_height = 106.5f;
private const float container_margin_y = 20;
private const float container_margin_x = 85;
public Action OnSelection;
public Bindable<ReleaseStreamInfo> SelectedRelease = new Bindable<ReleaseStreamInfo>();
public APIChangelog SelectedRelease;
public readonly FillFlowContainer<StreamBadge> BadgesContainer;
@ -45,31 +45,23 @@ namespace osu.Game.Overlays.Changelog
Left = container_margin_x,
Right = container_margin_x,
},
Children = new[]
{
new StreamBadge(StreamColour.STABLE, "Stable", "20180626.1", 16370, true),
new StreamBadge(StreamColour.BETA, "Beta", "20180626", 186),
new StreamBadge(StreamColour.LAZER, "Lazer", "2018.713.1"),
},
},
};
BadgesContainer.OnLoadComplete = d =>
// ok, so this is probably not the best.
// will need to reflect on this.
// do we need the changelog to be updateable?
BadgesContainer.OnUpdate = d =>
{
foreach (StreamBadge streamBadge in BadgesContainer.Children)
{
streamBadge.OnActivation = () =>
{
SelectedRelease.Value = new ReleaseStreamInfo
{
DisplayVersion = streamBadge.DisplayVersion,
IsFeatured = streamBadge.IsFeatured,
Name = streamBadge.Name,
Users = streamBadge.Users,
};
SelectedRelease = streamBadge.ChangelogEntry;
foreach (StreamBadge item in BadgesContainer.Children)
{
if (item.Name != streamBadge.Name) item.Deactivate();
if (item.ChangelogEntry.Id != streamBadge.ChangelogEntry.Id) item.Deactivate();
}
OnSelection?.Invoke();
};
}
};
@ -80,9 +72,9 @@ namespace osu.Game.Overlays.Changelog
// is this nullreference-safe for badgesContainer?
foreach (StreamBadge streamBadge in BadgesContainer.Children)
{
if (SelectedRelease.Value != null)
if (SelectedRelease != null)
{
if (SelectedRelease.Value.Name != streamBadge.Name)
if (SelectedRelease.UpdateStream.Id != streamBadge.ChangelogEntry.Id)
{
streamBadge.Deactivate();
}
@ -94,7 +86,7 @@ namespace osu.Game.Overlays.Changelog
protected override void OnHoverLost(InputState state)
{
if (SelectedRelease.Value == null)
if (SelectedRelease == null)
{
foreach (StreamBadge streamBadge in BadgesContainer.Children) streamBadge.Activate(true);
}

View File

@ -1,19 +0,0 @@
// 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.IO.Serialization;
namespace osu.Game.Overlays.Changelog
{
[Serializable]
public class ReleaseStreamInfo : IJsonSerializable
{
public string Name;
public string DisplayVersion;
public float Users;
public bool IsFeatured;
}
}

View File

@ -6,13 +6,14 @@ using osu.Framework.Allocation;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input;
using osu.Game.Graphics;
using osu.Game.Online.API.Requests.Responses;
using System;
namespace osu.Game.Overlays.Changelog.Streams
namespace osu.Game.Overlays.Changelog
{
public class StreamBadge : ClickableContainer
{
@ -26,19 +27,13 @@ namespace osu.Game.Overlays.Changelog.Streams
private readonly Header.LineBadge lineBadge;
private SampleChannel sampleHover;
public readonly string Name;
public readonly string DisplayVersion;
public readonly bool IsFeatured;
public readonly float Users;
public readonly APIChangelog ChangelogEntry;
public StreamBadge(ColourInfo colour, string streamName, string streamBuild, float onlineUsers = 0, bool isFeatured = false)
public StreamBadge(APIChangelog changelogEntry)
{
Name = streamName;
DisplayVersion = streamBuild;
IsFeatured = isFeatured;
Users = onlineUsers;
ChangelogEntry = changelogEntry;
Height = badge_height;
Width = isFeatured ? badge_width * 2 : badge_width;
Width = ChangelogEntry.IsFeatured ? badge_width * 2 : badge_width;
Margin = new MarginPadding(5);
isActivated = true;
Children = new Drawable[]
@ -52,7 +47,7 @@ namespace osu.Game.Overlays.Changelog.Streams
{
new SpriteText
{
Text = streamName,
Text = ChangelogEntry.UpdateStream.DisplayName,
Font = @"Exo2.0-Bold",
TextSize = 16,
Margin = new MarginPadding
@ -62,14 +57,14 @@ namespace osu.Game.Overlays.Changelog.Streams
},
new SpriteText
{
Text = streamBuild,
Text = ChangelogEntry.DisplayVersion,
Font = @"Exo2.0-Light",
TextSize = 21,
},
new SpriteText
{
Text = onlineUsers > 0 ?
string.Join(" ", onlineUsers.ToString("N0"), "users online"):
Text = ChangelogEntry.Users > 0 ?
string.Join(" ", ChangelogEntry.Users.ToString("N0"), "users online"):
null,
TextSize = 12,
Font = @"Exo2.0-Regular",
@ -82,7 +77,7 @@ namespace osu.Game.Overlays.Changelog.Streams
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
Width = 1,
Colour = colour,
Colour = StreamColour.FromStreamName(ChangelogEntry.UpdateStream.Name),
RelativeSizeAxes = Axes.X,
TransitionDuration = 600,
},

View File

@ -3,6 +3,7 @@
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@ -10,8 +11,10 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Input.Bindings;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Changelog;
using osu.Game.Overlays.Changelog.Streams;
namespace osu.Game.Overlays
{
@ -19,6 +22,9 @@ namespace osu.Game.Overlays
{
private readonly ChangelogHeader header;
public readonly ChangelogStreams Streams;
private APIChangelog changelogEntry;
private APIAccess api;
protected readonly Color4 Purple = new Color4(191, 4, 255, 255);
@ -36,6 +42,8 @@ namespace osu.Game.Overlays
Width = 0.85f;
Masking = true;
ChangelogContent content; // told by appveyor to conver to local variable..
EdgeEffect = new EdgeEffectParameters
{
Colour = Color4.Black.Opacity(0),
@ -64,25 +72,36 @@ namespace osu.Game.Overlays
{
header = new ChangelogHeader(),
Streams = new ChangelogStreams(),
new ChangelogChart(),
// will need to default to day-sorted content
content = new ChangelogContent(),
},
},
},
};
Streams.SelectedRelease.ValueChanged += r =>
Streams.OnSelection = () =>
{
if (Streams.SelectedRelease.Value != null)
header.ShowReleaseStream(r.Name, string.Join(" ", r.Name, r.DisplayVersion));
if (Streams.SelectedRelease != null)
{
header.ChangelogEntry = Streams.SelectedRelease;
}
header.ShowReleaseStream();
content.Clear();
content.Add(new ChangelogContentGroup(Streams.SelectedRelease));
};
Streams.BadgesContainer.OnLoadComplete += d =>
{
header.OnListingActivated += () =>
{
Streams.SelectedRelease.Value = null;
if (!Streams.IsHovered)
foreach (StreamBadge item in Streams.BadgesContainer.Children) item.Activate(true);
else
foreach (StreamBadge item in Streams.BadgesContainer.Children) item.Deactivate();
};
FetchChangelog();
};
header.OnListingActivated += () =>
{
Streams.SelectedRelease = null;
content.Clear();
// should add listing to content here
if (!Streams.IsHovered)
foreach (StreamBadge item in Streams.BadgesContainer.Children) item.Activate(true);
else
foreach (StreamBadge item in Streams.BadgesContainer.Children) item.Deactivate();
};
}
@ -120,5 +139,24 @@ namespace osu.Game.Overlays
base.PopOut();
FadeEdgeEffectTo(0, WaveContainer.DISAPPEAR_DURATION, Easing.Out);
}
[BackgroundDependencyLoader]
private void load(APIAccess api)
{
this.api = api;
}
public void FetchChangelog()
{
var req = new GetChangelogLatestBuildsRequest();
req.Success += res =>
{
foreach (APIChangelog item in res)
{
Streams.BadgesContainer.Add(new StreamBadge(item));
}
};
api.Queue(req);
}
}
}