mirror of
https://github.com/ppy/osu
synced 2024-12-28 01:42:57 +00:00
post a notification instead a screen
This commit is contained in:
parent
dfecddbf5d
commit
58844092d6
@ -1,13 +1,15 @@
|
||||
// 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.Linq;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Screens.Import;
|
||||
using osu.Game.Tests.Resources;
|
||||
|
||||
namespace osu.Game.Tests.Visual.Online
|
||||
@ -24,6 +26,12 @@ namespace osu.Game.Tests.Visual.Online
|
||||
OnlineBeatmapSetID = 173612,
|
||||
BeatmapSet = new APIBeatmapSet
|
||||
{
|
||||
Title = "FREEDOM Dive",
|
||||
Artist = "xi",
|
||||
Covers = new BeatmapSetOnlineCovers
|
||||
{
|
||||
Card = "https://assets.ppy.sh/beatmaps/173612/covers/card@2x.jpg"
|
||||
},
|
||||
OnlineID = 173612
|
||||
}
|
||||
};
|
||||
@ -40,7 +48,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
}
|
||||
});
|
||||
|
||||
AddUntilStep("Replay missing screen show", () => Game.ScreenStack.CurrentScreen.GetType() == typeof(ReplayMissingBeatmapScreen));
|
||||
AddUntilStep("Replay missing notification show", () => Game.Notifications.ChildrenOfType<MissingBeatmapNotification>().Any());
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -58,7 +66,7 @@ namespace osu.Game.Tests.Visual.Online
|
||||
}
|
||||
});
|
||||
|
||||
AddUntilStep("Replay missing screen not show", () => Game.ScreenStack.CurrentScreen.GetType() != typeof(ReplayMissingBeatmapScreen));
|
||||
AddUntilStep("Replay missing notification not show", () => !Game.Notifications.ChildrenOfType<MissingBeatmapNotification>().Any());
|
||||
}
|
||||
|
||||
private void setupBeatmapResponse(APIBeatmap b)
|
||||
|
157
osu.Game/Database/MissingBeatmapNotification.cs
Normal file
157
osu.Game/Database/MissingBeatmapNotification.cs
Normal file
@ -0,0 +1,157 @@
|
||||
// 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.IO;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Scoring;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Database
|
||||
{
|
||||
public partial class MissingBeatmapNotification : ProgressNotification
|
||||
{
|
||||
[Resolved]
|
||||
private BeatmapModelDownloader beatmapDownloader { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private ScoreManager scoreManager { get; set; } = null!;
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||
|
||||
[Resolved]
|
||||
private BeatmapSetOverlay? beatmapSetOverlay { get; set; }
|
||||
|
||||
private Container beatmapPanelContainer = null!;
|
||||
|
||||
private readonly MemoryStream scoreStream;
|
||||
|
||||
private readonly APIBeatmapSet beatmapSetInfo;
|
||||
|
||||
private BeatmapDownloadTracker? downloadTracker;
|
||||
|
||||
private Bindable<bool> autodownloadConfig = null!;
|
||||
|
||||
public MissingBeatmapNotification(APIBeatmap beatmap, MemoryStream scoreStream)
|
||||
{
|
||||
beatmapSetInfo = beatmap.BeatmapSet!;
|
||||
|
||||
this.scoreStream = scoreStream;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, OsuConfigManager config)
|
||||
{
|
||||
autodownloadConfig = config.GetBindable<bool>(OsuSetting.AutomaticallyDownloadWhenSpectating);
|
||||
|
||||
Text = "You do not have the required beatmap for this replay";
|
||||
|
||||
Content.Add(beatmapPanelContainer = new ClickableContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = 70,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.TopLeft,
|
||||
Action = () => beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmapSetInfo.OnlineID)
|
||||
});
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
downloadTracker = new BeatmapDownloadTracker(beatmapSetInfo);
|
||||
downloadTracker.State.BindValueChanged(downloadStatusChanged, true);
|
||||
|
||||
beatmapPanelContainer.Clear();
|
||||
beatmapPanelContainer.Child = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
CornerRadius = 4,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
downloadTracker,
|
||||
new DelayedLoadWrapper(() => new UpdateableOnlineBeatmapSetCover(BeatmapSetCoverType.Card)
|
||||
{
|
||||
OnlineInfo = beatmapSetInfo,
|
||||
RelativeSizeAxes = Axes.Both
|
||||
})
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Black,
|
||||
Alpha = 0.4f
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Left = 10f,
|
||||
Top = 5f
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new TruncatingSpriteText
|
||||
{
|
||||
Text = beatmapSetInfo.Title,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.SemiBold, size: 17, italics: true),
|
||||
RelativeSizeAxes = Axes.X,
|
||||
},
|
||||
new TruncatingSpriteText
|
||||
{
|
||||
Text = beatmapSetInfo.Artist,
|
||||
Font = OsuFont.GetFont(weight: FontWeight.SemiBold, size: 12, italics: true),
|
||||
RelativeSizeAxes = Axes.X,
|
||||
}
|
||||
}
|
||||
},
|
||||
new DownloadButton
|
||||
{
|
||||
Anchor = Anchor.BottomCentre,
|
||||
Origin = Anchor.BottomCentre,
|
||||
Width = 50,
|
||||
Height = 30,
|
||||
Margin = new MarginPadding
|
||||
{
|
||||
Bottom = 1f
|
||||
},
|
||||
Action = () => beatmapDownloader.Download(beatmapSetInfo),
|
||||
State = { BindTarget = downloadTracker.State }
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (autodownloadConfig.Value)
|
||||
beatmapDownloader.Download(beatmapSetInfo);
|
||||
}
|
||||
|
||||
private void downloadStatusChanged(ValueChangedEvent<DownloadState> status)
|
||||
{
|
||||
if (status.NewValue != DownloadState.LocallyAvailable)
|
||||
return;
|
||||
|
||||
var importTask = new ImportTask(scoreStream, "score.osr");
|
||||
scoreManager.Import(this, new[] { importTask });
|
||||
}
|
||||
}
|
||||
}
|
@ -854,8 +854,6 @@ namespace osu.Game
|
||||
|
||||
MultiplayerClient.PostNotification = n => Notifications.Post(n);
|
||||
|
||||
ScoreManager.Performer = this;
|
||||
|
||||
// make config aware of how to lookup skins for on-screen display purposes.
|
||||
// if this becomes a more common thing, tracked settings should be reconsidered to allow local DI.
|
||||
LocalConfig.LookupSkinName = id => SkinManager.Query(s => s.ID == id)?.ToString() ?? "Unknown";
|
||||
|
@ -10,7 +10,6 @@ using System.Threading;
|
||||
using Newtonsoft.Json;
|
||||
using osu.Framework.Logging;
|
||||
using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.IO.Archives;
|
||||
@ -21,8 +20,6 @@ using osu.Game.Online.API.Requests;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Screens;
|
||||
using osu.Game.Screens.Import;
|
||||
using Realms;
|
||||
|
||||
namespace osu.Game.Scoring
|
||||
@ -31,8 +28,6 @@ namespace osu.Game.Scoring
|
||||
{
|
||||
public override IEnumerable<string> HandledExtensions => new[] { ".osr" };
|
||||
|
||||
public IPerformFromScreenRunner? Performer { get; set; }
|
||||
|
||||
protected override string[] HashableFileTypes => new[] { ".osr" };
|
||||
|
||||
private readonly RulesetStore rulesets;
|
||||
@ -69,9 +64,6 @@ namespace osu.Game.Scoring
|
||||
|
||||
private void onMissingBeatmap(LegacyScoreDecoder.BeatmapNotFoundException e, ArchiveReader archive, string name)
|
||||
{
|
||||
if (Performer == null)
|
||||
return;
|
||||
|
||||
var stream = new MemoryStream();
|
||||
|
||||
// stream will close after exception throw, so fetch the stream again.
|
||||
@ -87,7 +79,7 @@ namespace osu.Game.Scoring
|
||||
|
||||
req.Success += res =>
|
||||
{
|
||||
Performer.PerformFromScreen(screen => screen.Push(new ReplayMissingBeatmapScreen(res, stream)));
|
||||
PostNotification?.Invoke(new MissingBeatmapNotification(res, stream));
|
||||
};
|
||||
|
||||
api.Queue(req);
|
||||
|
@ -21,7 +21,6 @@ using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Scoring.Legacy;
|
||||
using osu.Game.Screens;
|
||||
|
||||
namespace osu.Game.Scoring
|
||||
{
|
||||
@ -31,12 +30,6 @@ namespace osu.Game.Scoring
|
||||
private readonly ScoreImporter scoreImporter;
|
||||
private readonly LegacyScoreExporter scoreExporter;
|
||||
|
||||
[CanBeNull]
|
||||
public IPerformFromScreenRunner Performer
|
||||
{
|
||||
set => scoreImporter.Performer = value;
|
||||
}
|
||||
|
||||
public override bool PauseImports
|
||||
{
|
||||
get => base.PauseImports;
|
||||
|
@ -1,199 +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.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.Drawables.Cards;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Database;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Online.API.Requests.Responses;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.Settings;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Ranking;
|
||||
using osuTK;
|
||||
using Realms;
|
||||
|
||||
namespace osu.Game.Screens.Import
|
||||
{
|
||||
[Cached(typeof(IPreviewTrackOwner))]
|
||||
public partial class ReplayMissingBeatmapScreen : OsuScreen, IPreviewTrackOwner
|
||||
{
|
||||
[Resolved]
|
||||
private BeatmapModelDownloader beatmapDownloader { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private ScoreManager scoreManager { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private RealmAccess realm { get; set; } = null!;
|
||||
|
||||
private IDisposable? realmSubscription;
|
||||
|
||||
[Cached]
|
||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||
|
||||
[Resolved]
|
||||
private INotificationOverlay? notificationOverlay { get; set; }
|
||||
|
||||
private Container beatmapPanelContainer = null!;
|
||||
private ReplayDownloadButton replayDownloadButton = null!;
|
||||
private SettingsCheckbox automaticDownload = null!;
|
||||
|
||||
private readonly MemoryStream scoreStream;
|
||||
|
||||
private readonly APIBeatmapSet beatmapSetInfo;
|
||||
|
||||
public ReplayMissingBeatmapScreen(APIBeatmap beatmap, MemoryStream scoreStream)
|
||||
{
|
||||
beatmapSetInfo = beatmap.BeatmapSet!;
|
||||
|
||||
this.scoreStream = scoreStream;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuColour colours, OsuConfigManager config)
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
Masking = true,
|
||||
CornerRadius = 20,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
AutoSizeDuration = 500,
|
||||
AutoSizeEasing = Easing.OutQuint,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
Colour = colours.Gray5,
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Margin = new MarginPadding(20),
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Spacing = new Vector2(15),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = "Beatmap info",
|
||||
Font = OsuFont.Default.With(size: 30),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Spacing = new Vector2(15),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
beatmapPanelContainer = new Container
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
},
|
||||
}
|
||||
},
|
||||
automaticDownload = new SettingsCheckbox
|
||||
{
|
||||
LabelText = "Automatically download beatmaps",
|
||||
Current = config.GetBindable<bool>(OsuSetting.AutomaticallyDownloadWhenSpectating),
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
replayDownloadButton = new ReplayDownloadButton(new ScoreInfo())
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
base.LoadComplete();
|
||||
|
||||
updateStatus();
|
||||
realmSubscription = realm.RegisterForNotifications(
|
||||
realm => realm.All<BeatmapSetInfo>().Where(s => !s.DeletePending), beatmapsChanged);
|
||||
}
|
||||
|
||||
private void updateStatus()
|
||||
{
|
||||
beatmapPanelContainer.Clear();
|
||||
beatmapPanelContainer.Child = new BeatmapCardNormal(beatmapSetInfo, allowExpansion: false);
|
||||
checkForAutomaticDownload(beatmapSetInfo);
|
||||
}
|
||||
|
||||
private void checkForAutomaticDownload(APIBeatmapSet beatmap)
|
||||
{
|
||||
if (!automaticDownload.Current.Value)
|
||||
return;
|
||||
|
||||
beatmapDownloader.Download(beatmap);
|
||||
}
|
||||
|
||||
private void beatmapsChanged(IRealmCollection<BeatmapSetInfo> sender, ChangeSet? changes)
|
||||
{
|
||||
if (changes?.InsertedIndices == null) return;
|
||||
|
||||
if (!scoreStream.CanRead) return;
|
||||
|
||||
if (sender.Any(b => b.OnlineID == beatmapSetInfo.OnlineID))
|
||||
{
|
||||
var progressNotification = new ImportProgressNotification();
|
||||
var importTask = new ImportTask(scoreStream, "score.osr");
|
||||
scoreManager.Import(progressNotification, new[] { importTask })
|
||||
.ContinueWith(s =>
|
||||
{
|
||||
s.GetResultSafely<IEnumerable<Live<ScoreInfo>>>().FirstOrDefault()?.PerformRead(score =>
|
||||
{
|
||||
Guid scoreid = score.ID;
|
||||
Scheduler.Add(() =>
|
||||
{
|
||||
replayDownloadButton.Score.Value = realm.Realm.Find<ScoreInfo>(scoreid) ?? new ScoreInfo();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
notificationOverlay?.Post(progressNotification);
|
||||
|
||||
realmSubscription?.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
realmSubscription?.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user