diff --git a/osu.Game/Collections/BeatmapCollectionManager.cs b/osu.Game/Collections/BeatmapCollectionManager.cs
index a553ac632e..6a5ed6bbbc 100644
--- a/osu.Game/Collections/BeatmapCollectionManager.cs
+++ b/osu.Game/Collections/BeatmapCollectionManager.cs
@@ -57,6 +57,10 @@ namespace osu.Game.Collections
c.Changed += backgroundSave;
Collections.CollectionChanged += (_, __) => backgroundSave();
}
+ ///
+ /// Set an endpoint for notifications to be posted to.
+ ///
+ public Action PostNotification { protected get; set; }
///
/// Set a storage with access to an osu-stable install for import purposes.
@@ -93,9 +97,25 @@ namespace osu.Game.Collections
});
}
- public async Task Import(Stream stream) => await Task.Run(async () =>
+ public async Task Import(Stream stream)
{
- var collection = readCollections(stream);
+ var notification = new ProgressNotification
+ {
+ State = ProgressNotificationState.Active,
+ Text = "Collections import is initialising..."
+ };
+
+ PostNotification?.Invoke(notification);
+
+ await import(stream, notification);
+ }
+
+ private async Task import(Stream stream, ProgressNotification notification = null) => await Task.Run(async () =>
+ {
+ if (notification != null)
+ notification.Progress = 0;
+
+ var collection = readCollections(stream, notification);
bool importCompleted = false;
Schedule(() =>
@@ -106,6 +126,12 @@ namespace osu.Game.Collections
while (!IsDisposed && !importCompleted)
await Task.Delay(10);
+
+ if (notification != null)
+ {
+ notification.CompletionText = $"Imported {collection.Count} collections";
+ notification.State = ProgressNotificationState.Completed;
+ }
});
private void importCollections(List newCollections)
@@ -124,8 +150,14 @@ namespace osu.Game.Collections
}
}
- private List readCollections(Stream stream)
+ private List readCollections(Stream stream, ProgressNotification notification = null)
{
+ if (notification != null)
+ {
+ notification.Text = "Reading collections...";
+ notification.Progress = 0;
+ }
+
var result = new List();
try
@@ -139,11 +171,17 @@ namespace osu.Game.Collections
for (int i = 0; i < collectionCount; i++)
{
+ if (notification?.CancellationToken.IsCancellationRequested == true)
+ return result;
+
var collection = new BeatmapCollection { Name = { Value = sr.ReadString() } };
int mapCount = sr.ReadInt32();
for (int j = 0; j < mapCount; j++)
{
+ if (notification?.CancellationToken.IsCancellationRequested == true)
+ return result;
+
string checksum = sr.ReadString();
var beatmap = beatmaps.QueryBeatmap(b => b.MD5Hash == checksum);
@@ -151,6 +189,12 @@ namespace osu.Game.Collections
collection.Beatmaps.Add(beatmap);
}
+ if (notification != null)
+ {
+ notification.Text = $"Imported {i + 1} of {collectionCount} collections";
+ notification.Progress = (float)(i + 1) / collectionCount;
+ }
+
result.Add(collection);
}
}
@@ -163,6 +207,12 @@ namespace osu.Game.Collections
return result;
}
+ public void DeleteAll()
+ {
+ Collections.Clear();
+ PostNotification?.Invoke(new SimpleNotification { Text = "Deleted all collections!" });
+ }
+
private readonly object saveLock = new object();
private int lastSave;
private int saveFailures;
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index 8434ee11fa..33a353742d 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -537,6 +537,7 @@ namespace osu.Game
ScoreManager.GetStableStorage = GetStorageForStableInstall;
ScoreManager.PresentImport = items => PresentScore(items.First());
+ CollectionManager.PostNotification = n => notifications.Post(n);
CollectionManager.GetStableStorage = GetStorageForStableInstall;
Container logoContainer;
diff --git a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs
index 74f9920ae0..30fd5921eb 100644
--- a/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/Maintenance/GeneralSettings.cs
@@ -126,7 +126,7 @@ namespace osu.Game.Overlays.Settings.Sections.Maintenance
Text = "Delete ALL collections",
Action = () =>
{
- dialogOverlay?.Push(new DeleteAllBeatmapsDialog(() => collectionManager.Collections.Clear()));
+ dialogOverlay?.Push(new DeleteAllBeatmapsDialog(collectionManager.DeleteAll));
}
});