mirror of
https://github.com/osukey/osukey.git
synced 2025-08-05 07:33:55 +09:00
Merge remote-tracking branch 'upstream/master' into non-timeoffset-judgements
This commit is contained in:
21
osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs
Normal file
21
osu.Game/Online/API/Requests/GetUserKudosuHistoryRequest.cs
Normal file
@ -0,0 +1,21 @@
|
||||
// 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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
|
||||
namespace osu.Game.Online.API.Requests
|
||||
{
|
||||
public class GetUserKudosuHistoryRequest : PaginatedAPIRequest<List<APIKudosuHistory>>
|
||||
{
|
||||
private readonly long userId;
|
||||
|
||||
public GetUserKudosuHistoryRequest(long userId, int page = 0, int itemsPerPage = 5)
|
||||
: base(page, itemsPerPage)
|
||||
{
|
||||
this.userId = userId;
|
||||
}
|
||||
|
||||
protected override string Target => $"users/{userId}/kudosu";
|
||||
}
|
||||
}
|
83
osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs
Normal file
83
osu.Game/Online/API/Requests/Responses/APIKudosuHistory.cs
Normal file
@ -0,0 +1,83 @@
|
||||
// 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.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace osu.Game.Online.API.Requests.Responses
|
||||
{
|
||||
public class APIKudosuHistory
|
||||
{
|
||||
[JsonProperty("created_at")]
|
||||
public DateTimeOffset CreatedAt;
|
||||
|
||||
[JsonProperty("amount")]
|
||||
public int Amount;
|
||||
|
||||
[JsonProperty("post")]
|
||||
public ModdingPost Post;
|
||||
|
||||
public class ModdingPost
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public string Url;
|
||||
|
||||
[JsonProperty("title")]
|
||||
public string Title;
|
||||
}
|
||||
|
||||
[JsonProperty("giver")]
|
||||
public KudosuGiver Giver;
|
||||
|
||||
public class KudosuGiver
|
||||
{
|
||||
[JsonProperty("url")]
|
||||
public string Url;
|
||||
|
||||
[JsonProperty("username")]
|
||||
public string Username;
|
||||
}
|
||||
|
||||
public KudosuSource Source;
|
||||
|
||||
public KudosuAction Action;
|
||||
|
||||
[JsonProperty("action")]
|
||||
private string action
|
||||
{
|
||||
set
|
||||
{
|
||||
// incoming action may contain a prefix. if it doesn't, it's a legacy forum event.
|
||||
|
||||
string[] split = value.Split('.');
|
||||
|
||||
if (split.Length > 1)
|
||||
Enum.TryParse(split.First().Replace("_", ""), true, out Source);
|
||||
else
|
||||
Source = KudosuSource.Forum;
|
||||
|
||||
Enum.TryParse(split.Last(), true, out Action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum KudosuSource
|
||||
{
|
||||
Unknown,
|
||||
AllowKudosu,
|
||||
Delete,
|
||||
DenyKudosu,
|
||||
Forum,
|
||||
Recalculate,
|
||||
Restore,
|
||||
Vote
|
||||
}
|
||||
|
||||
public enum KudosuAction
|
||||
{
|
||||
Give,
|
||||
Reset,
|
||||
Revoke,
|
||||
}
|
||||
}
|
@ -0,0 +1,147 @@
|
||||
// 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.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.Chat;
|
||||
using System;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
||||
{
|
||||
public class DrawableKudosuHistoryItem : CompositeDrawable
|
||||
{
|
||||
private const int height = 25;
|
||||
|
||||
[Resolved]
|
||||
private OsuColour colours { get; set; }
|
||||
|
||||
private readonly APIKudosuHistory historyItem;
|
||||
private readonly LinkFlowContainer linkFlowContainer;
|
||||
private readonly DrawableDate date;
|
||||
|
||||
public DrawableKudosuHistoryItem(APIKudosuHistory historyItem)
|
||||
{
|
||||
this.historyItem = historyItem;
|
||||
|
||||
Height = height;
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
linkFlowContainer = new LinkFlowContainer
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Spacing = new Vector2(0, 3),
|
||||
},
|
||||
date = new DrawableDate(historyItem.CreatedAt)
|
||||
{
|
||||
Anchor = Anchor.CentreRight,
|
||||
Origin = Anchor.CentreRight,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
date.Colour = colours.GreySeafoamLighter;
|
||||
var formattedSource = MessageFormatter.FormatText(getString(historyItem));
|
||||
linkFlowContainer.AddLinks(formattedSource.Text, formattedSource.Links);
|
||||
}
|
||||
|
||||
private string getString(APIKudosuHistory item)
|
||||
{
|
||||
string amount = $"{Math.Abs(item.Amount)} kudosu";
|
||||
string post = $"[{item.Post.Title}]({item.Post.Url})";
|
||||
|
||||
switch (item.Source)
|
||||
{
|
||||
case KudosuSource.AllowKudosu:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from kudosu deny repeal of modding post {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.DenyKudosu:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Reset:
|
||||
return $"Denied {amount} from modding post {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Delete:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Reset:
|
||||
return $"Lost {amount} from modding post deletion of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Restore:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from modding post restoration of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Vote:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from obtaining votes in modding post of {post}";
|
||||
|
||||
case KudosuAction.Reset:
|
||||
return $"Lost {amount} from losing votes in modding post of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Recalculate:
|
||||
switch (item.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from votes recalculation in modding post of {post}";
|
||||
|
||||
case KudosuAction.Reset:
|
||||
return $"Lost {amount} from votes recalculation in modding post of {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case KudosuSource.Forum:
|
||||
|
||||
string giver = $"[{item.Giver?.Username}]({item.Giver?.Url})";
|
||||
|
||||
switch (historyItem.Action)
|
||||
{
|
||||
case KudosuAction.Give:
|
||||
return $"Received {amount} from {giver} for a post at {post}";
|
||||
|
||||
case KudosuAction.Reset:
|
||||
return $"Kudosu reset by {giver} for the post {post}";
|
||||
|
||||
case KudosuAction.Revoke:
|
||||
return $"Denied kudosu by {giver} for the post {post}";
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return $"Unknown event ({amount} change)";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
// 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.
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Users;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Online.API;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections.Kudosu
|
||||
{
|
||||
public class PaginatedKudosuHistoryContainer : PaginatedContainer<APIKudosuHistory>
|
||||
{
|
||||
public PaginatedKudosuHistoryContainer(Bindable<User> user, string header, string missing)
|
||||
: base(user, header, missing)
|
||||
{
|
||||
ItemsPerPage = 5;
|
||||
}
|
||||
|
||||
protected override APIRequest<List<APIKudosuHistory>> CreateRequest()
|
||||
=> new GetUserKudosuHistoryRequest(User.Value.Id, VisiblePages++, ItemsPerPage);
|
||||
|
||||
protected override Drawable CreateDrawableItem(APIKudosuHistory item) => new DrawableKudosuHistoryItem(item);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
// 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.
|
||||
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Overlays.Profile.Sections.Kudosu;
|
||||
|
||||
namespace osu.Game.Overlays.Profile.Sections
|
||||
@ -13,9 +14,10 @@ namespace osu.Game.Overlays.Profile.Sections
|
||||
|
||||
public KudosuSection()
|
||||
{
|
||||
Children = new[]
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new KudosuInfo(User),
|
||||
new PaginatedKudosuHistoryContainer(User, null, @"This user hasn't received any kudosu!"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.TypeExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Primitives;
|
||||
using osu.Framework.Threading;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
@ -278,6 +279,14 @@ namespace osu.Game.Rulesets.Objects.Drawables
|
||||
UpdateResult(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Schedules an <see cref="Action"/> to this <see cref="DrawableHitObject"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Only provided temporarily until hitobject pooling is implemented.
|
||||
/// </remarks>
|
||||
protected internal new ScheduledDelegate Schedule(Action action) => base.Schedule(action);
|
||||
|
||||
private double? lifetimeStart;
|
||||
|
||||
public override double LifetimeStart
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Caching;
|
||||
@ -50,8 +51,13 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
public override bool Remove(DrawableHitObject hitObject)
|
||||
{
|
||||
var result = base.Remove(hitObject);
|
||||
|
||||
if (result)
|
||||
{
|
||||
initialStateCache.Invalidate();
|
||||
hitObjectInitialStateCache.Remove(hitObject);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -86,13 +92,34 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
scrollingInfo.Algorithm.Reset();
|
||||
|
||||
foreach (var obj in Objects)
|
||||
{
|
||||
computeLifetimeStartRecursive(obj);
|
||||
computeInitialStateRecursive(obj);
|
||||
}
|
||||
|
||||
initialStateCache.Validate();
|
||||
}
|
||||
}
|
||||
|
||||
private void computeInitialStateRecursive(DrawableHitObject hitObject)
|
||||
private void computeLifetimeStartRecursive(DrawableHitObject hitObject)
|
||||
{
|
||||
hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value);
|
||||
|
||||
foreach (var obj in hitObject.NestedHitObjects)
|
||||
computeLifetimeStartRecursive(obj);
|
||||
}
|
||||
|
||||
private readonly Dictionary<DrawableHitObject, Cached> hitObjectInitialStateCache = new Dictionary<DrawableHitObject, Cached>();
|
||||
|
||||
// Cant use AddOnce() since the delegate is re-constructed every invocation
|
||||
private void computeInitialStateRecursive(DrawableHitObject hitObject) => hitObject.Schedule(() =>
|
||||
{
|
||||
if (!hitObjectInitialStateCache.TryGetValue(hitObject, out var cached))
|
||||
cached = hitObjectInitialStateCache[hitObject] = new Cached();
|
||||
|
||||
if (cached.IsValid)
|
||||
return;
|
||||
|
||||
double endTime = hitObject.HitObject.StartTime;
|
||||
|
||||
if (hitObject.HitObject is IHasEndTime e)
|
||||
@ -113,7 +140,6 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
}
|
||||
}
|
||||
|
||||
hitObject.LifetimeStart = scrollingInfo.Algorithm.GetDisplayStartTime(hitObject.HitObject.StartTime, timeRange.Value);
|
||||
hitObject.LifetimeEnd = scrollingInfo.Algorithm.TimeAt(scrollLength * safe_lifetime_end_multiplier, endTime, timeRange.Value, scrollLength);
|
||||
|
||||
foreach (var obj in hitObject.NestedHitObjects)
|
||||
@ -123,7 +149,9 @@ namespace osu.Game.Rulesets.UI.Scrolling
|
||||
// Nested hitobjects don't need to scroll, but they do need accurate positions
|
||||
updatePosition(obj, hitObject.HitObject.StartTime);
|
||||
}
|
||||
}
|
||||
|
||||
cached.Validate();
|
||||
});
|
||||
|
||||
protected override void UpdateAfterChildrenLife()
|
||||
{
|
||||
|
@ -414,7 +414,11 @@ namespace osu.Game.Screens.Select
|
||||
{
|
||||
Logger.Log($"beatmap changed from \"{Beatmap.Value.BeatmapInfo}\" to \"{beatmap}\"");
|
||||
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value);
|
||||
WorkingBeatmap previous = Beatmap.Value;
|
||||
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, previous);
|
||||
|
||||
if (this.IsCurrentScreen() && Beatmap.Value?.Track != previous?.Track)
|
||||
ensurePlayingSelected();
|
||||
|
||||
if (beatmap != null)
|
||||
{
|
||||
@ -425,8 +429,6 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
}
|
||||
|
||||
if (this.IsCurrentScreen())
|
||||
ensurePlayingSelected();
|
||||
UpdateBeatmap(Beatmap.Value);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user