mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 16:12:57 +08:00
Merge pull request #4000 from m2307/master
Implement clear scores on beatmap
This commit is contained in:
commit
10a3b409b2
@ -12,7 +12,7 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handles the storage and retrieval of Beatmaps/BeatmapSets to the database backing
|
/// Handles the storage and retrieval of Beatmaps/BeatmapSets to the database backing
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BeatmapStore : MutableDatabaseBackedStore<BeatmapSetInfo>
|
public class BeatmapStore : MutableDatabaseBackedStoreWithFileIncludes<BeatmapSetInfo, BeatmapSetFileInfo>
|
||||||
{
|
{
|
||||||
public event Action<BeatmapInfo> BeatmapHidden;
|
public event Action<BeatmapInfo> BeatmapHidden;
|
||||||
public event Action<BeatmapInfo> BeatmapRestored;
|
public event Action<BeatmapInfo> BeatmapRestored;
|
||||||
@ -64,18 +64,17 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected override IQueryable<BeatmapSetInfo> AddIncludesForDeletion(IQueryable<BeatmapSetInfo> query) =>
|
protected override IQueryable<BeatmapSetInfo> AddIncludesForDeletion(IQueryable<BeatmapSetInfo> query) =>
|
||||||
base.AddIncludesForDeletion(query)
|
base.AddIncludesForDeletion(query)
|
||||||
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
|
|
||||||
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
|
|
||||||
.Include(s => s.Metadata)
|
.Include(s => s.Metadata)
|
||||||
.Include(s => s.Beatmaps).ThenInclude(b => b.Scores);
|
.Include(s => s.Beatmaps).ThenInclude(b => b.Scores)
|
||||||
|
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
|
||||||
|
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata);
|
||||||
|
|
||||||
protected override IQueryable<BeatmapSetInfo> AddIncludesForConsumption(IQueryable<BeatmapSetInfo> query) =>
|
protected override IQueryable<BeatmapSetInfo> AddIncludesForConsumption(IQueryable<BeatmapSetInfo> query) =>
|
||||||
base.AddIncludesForConsumption(query)
|
base.AddIncludesForConsumption(query)
|
||||||
.Include(s => s.Metadata)
|
.Include(s => s.Metadata)
|
||||||
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
|
.Include(s => s.Beatmaps).ThenInclude(s => s.Ruleset)
|
||||||
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
|
.Include(s => s.Beatmaps).ThenInclude(b => b.BaseDifficulty)
|
||||||
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata)
|
.Include(s => s.Beatmaps).ThenInclude(b => b.Metadata);
|
||||||
.Include(s => s.Files).ThenInclude(f => f.FileInfo);
|
|
||||||
|
|
||||||
protected override void Purge(List<BeatmapSetInfo> items, OsuDbContext context)
|
protected override void Purge(List<BeatmapSetInfo> items, OsuDbContext context)
|
||||||
{
|
{
|
||||||
|
@ -108,7 +108,7 @@ namespace osu.Game.Database
|
|||||||
a.Invoke();
|
a.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ArchiveModelManager(Storage storage, IDatabaseContextFactory contextFactory, MutableDatabaseBackedStore<TModel> modelStore, IIpcHost importHost = null)
|
protected ArchiveModelManager(Storage storage, IDatabaseContextFactory contextFactory, MutableDatabaseBackedStoreWithFileIncludes<TModel, TFileModel> modelStore, IIpcHost importHost = null)
|
||||||
{
|
{
|
||||||
ContextFactory = contextFactory;
|
ContextFactory = contextFactory;
|
||||||
|
|
||||||
|
@ -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 System.Linq;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
|
||||||
|
namespace osu.Game.Database
|
||||||
|
{
|
||||||
|
public abstract class MutableDatabaseBackedStoreWithFileIncludes<T, U> : MutableDatabaseBackedStore<T>
|
||||||
|
where T : class, IHasPrimaryKey, ISoftDelete, IHasFiles<U>
|
||||||
|
where U : INamedFileInfo
|
||||||
|
{
|
||||||
|
protected MutableDatabaseBackedStoreWithFileIncludes(IDatabaseContextFactory contextFactory, Storage storage = null)
|
||||||
|
: base(contextFactory, storage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IQueryable<T> AddIncludesForConsumption(IQueryable<T> query) =>
|
||||||
|
base.AddIncludesForConsumption(query)
|
||||||
|
.Include(s => s.Files).ThenInclude(f => f.FileInfo);
|
||||||
|
|
||||||
|
protected override IQueryable<T> AddIncludesForDeletion(IQueryable<T> query) =>
|
||||||
|
base.AddIncludesForDeletion(query)
|
||||||
|
.Include(s => s.Files); // don't include FileInfo. these are handled by the FileStore itself.
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ using osu.Game.Database;
|
|||||||
|
|
||||||
namespace osu.Game.Scoring
|
namespace osu.Game.Scoring
|
||||||
{
|
{
|
||||||
public class ScoreStore : MutableDatabaseBackedStore<ScoreInfo>
|
public class ScoreStore : MutableDatabaseBackedStoreWithFileIncludes<ScoreInfo, ScoreFileInfo>
|
||||||
{
|
{
|
||||||
public ScoreStore(IDatabaseContextFactory factory, Storage storage)
|
public ScoreStore(IDatabaseContextFactory factory, Storage storage)
|
||||||
: base(factory, storage)
|
: base(factory, storage)
|
||||||
@ -17,7 +17,6 @@ namespace osu.Game.Scoring
|
|||||||
|
|
||||||
protected override IQueryable<ScoreInfo> AddIncludesForConsumption(IQueryable<ScoreInfo> query)
|
protected override IQueryable<ScoreInfo> AddIncludesForConsumption(IQueryable<ScoreInfo> query)
|
||||||
=> base.AddIncludesForConsumption(query)
|
=> base.AddIncludesForConsumption(query)
|
||||||
.Include(s => s.Files).ThenInclude(f => f.FileInfo)
|
|
||||||
.Include(s => s.Beatmap)
|
.Include(s => s.Beatmap)
|
||||||
.Include(s => s.Ruleset);
|
.Include(s => s.Ruleset);
|
||||||
}
|
}
|
||||||
|
48
osu.Game/Screens/Select/BeatmapClearScoresDialog.cs
Normal file
48
osu.Game/Screens/Select/BeatmapClearScoresDialog.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// 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.Game.Beatmaps;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Overlays.Dialog;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace osu.Game.Screens.Select
|
||||||
|
{
|
||||||
|
public class BeatmapClearScoresDialog : PopupDialog
|
||||||
|
{
|
||||||
|
private ScoreManager scoreManager;
|
||||||
|
|
||||||
|
public BeatmapClearScoresDialog(BeatmapInfo beatmap, Action onCompletion)
|
||||||
|
{
|
||||||
|
BodyText = $@"{beatmap.Metadata?.Artist} - {beatmap.Metadata?.Title}";
|
||||||
|
Icon = FontAwesome.fa_eraser;
|
||||||
|
HeaderText = @"Clearing all local scores. Are you sure?";
|
||||||
|
Buttons = new PopupDialogButton[]
|
||||||
|
{
|
||||||
|
new PopupDialogOkButton
|
||||||
|
{
|
||||||
|
Text = @"Yes. Please.",
|
||||||
|
Action = () =>
|
||||||
|
{
|
||||||
|
Task.Run(() => scoreManager.Delete(scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == beatmap.ID).ToList()))
|
||||||
|
.ContinueWith(_ => onCompletion);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new PopupDialogCancelButton
|
||||||
|
{
|
||||||
|
Text = @"No, I'm still attached.",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(ScoreManager scoreManager)
|
||||||
|
{
|
||||||
|
this.scoreManager = scoreManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select.Leaderboards
|
|||||||
{
|
{
|
||||||
if (Scope == BeatmapLeaderboardScope.Local)
|
if (Scope == BeatmapLeaderboardScope.Local)
|
||||||
{
|
{
|
||||||
Scores = scoreManager.QueryScores(s => s.Beatmap.ID == Beatmap.ID).ToArray();
|
Scores = scoreManager.QueryScores(s => !s.DeletePending && s.Beatmap.ID == Beatmap.ID).ToArray();
|
||||||
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,6 @@
|
|||||||
// 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;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osuTK;
|
|
||||||
using osuTK.Input;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
@ -13,8 +8,8 @@ using osu.Framework.Audio.Track;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Logging;
|
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
using osu.Framework.Threading;
|
using osu.Framework.Threading;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -31,7 +26,12 @@ using osu.Game.Screens.Menu;
|
|||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Screens.Select.Options;
|
using osu.Game.Screens.Select.Options;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
using osuTK.Input;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Select
|
namespace osu.Game.Screens.Select
|
||||||
{
|
{
|
||||||
@ -226,7 +226,7 @@ namespace osu.Game.Screens.Select
|
|||||||
|
|
||||||
BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.fa_trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue);
|
BeatmapOptions.AddButton(@"Delete", @"all difficulties", FontAwesome.fa_trash, colours.Pink, () => delete(Beatmap.Value.BeatmapSetInfo), Key.Number4, float.MaxValue);
|
||||||
BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1);
|
BeatmapOptions.AddButton(@"Remove", @"from unplayed", FontAwesome.fa_times_circle_o, colours.Purple, null, Key.Number1);
|
||||||
BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, colours.Purple, null, Key.Number2);
|
BeatmapOptions.AddButton(@"Clear", @"local scores", FontAwesome.fa_eraser, colours.Purple, () => clearScores(Beatmap.Value.BeatmapInfo), Key.Number2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.beatmaps == null)
|
if (this.beatmaps == null)
|
||||||
@ -621,6 +621,15 @@ namespace osu.Game.Screens.Select
|
|||||||
dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap));
|
dialogOverlay?.Push(new BeatmapDeleteDialog(beatmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearScores(BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
if (beatmap == null || beatmap.ID <= 0) return;
|
||||||
|
|
||||||
|
dialogOverlay?.Push(new BeatmapClearScoresDialog(beatmap, () =>
|
||||||
|
// schedule done here rather than inside the dialog as the dialog may fade out and never callback.
|
||||||
|
Schedule(() => BeatmapDetails.Leaderboard.RefreshScores())));
|
||||||
|
}
|
||||||
|
|
||||||
public override bool OnPressed(GlobalAction action)
|
public override bool OnPressed(GlobalAction action)
|
||||||
{
|
{
|
||||||
if (!this.IsCurrentScreen()) return false;
|
if (!this.IsCurrentScreen()) return false;
|
||||||
|
@ -1,22 +1,16 @@
|
|||||||
// 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.Linq;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
public class SkinStore : MutableDatabaseBackedStore<SkinInfo>
|
public class SkinStore : MutableDatabaseBackedStoreWithFileIncludes<SkinInfo, SkinFileInfo>
|
||||||
{
|
{
|
||||||
public SkinStore(DatabaseContextFactory contextFactory, Storage storage = null)
|
public SkinStore(DatabaseContextFactory contextFactory, Storage storage = null)
|
||||||
: base(contextFactory, storage)
|
: base(contextFactory, storage)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IQueryable<SkinInfo> AddIncludesForConsumption(IQueryable<SkinInfo> query) =>
|
|
||||||
base.AddIncludesForConsumption(query)
|
|
||||||
.Include(s => s.Files).ThenInclude(f => f.FileInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user