Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add notification on daily challenge conclusion & start of new one #29188

Merged
merged 9 commits into from
Jul 31, 2024
73 changes: 73 additions & 0 deletions osu.Game.Tests/Visual/DailyChallenge/TestSceneDailyChallenge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,32 @@
using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Game.Online.API;
using osu.Game.Online.Metadata;
using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Tests.Resources;
using osu.Game.Tests.Visual.Metadata;
using osu.Game.Tests.Visual.OnlinePlay;

namespace osu.Game.Tests.Visual.DailyChallenge
{
public partial class TestSceneDailyChallenge : OnlinePlayTestScene
{
[Cached(typeof(MetadataClient))]
private TestMetadataClient metadataClient = new TestMetadataClient();

[Cached(typeof(INotificationOverlay))]
private NotificationOverlay notificationOverlay = new NotificationOverlay();

[BackgroundDependencyLoader]
private void load()
{
base.Content.Add(notificationOverlay);
}

[Test]
public void TestDailyChallenge()
{
Expand All @@ -36,5 +52,62 @@ public void TestDailyChallenge()
AddStep("add room", () => API.Perform(new CreateRoomRequest(room)));
AddStep("push screen", () => LoadScreen(new Screens.OnlinePlay.DailyChallenge.DailyChallenge(room)));
}

[Test]
public void TestNotifications()
{
var room = new Room
{
RoomID = { Value = 1234 },
Name = { Value = "Daily Challenge: June 4, 2024" },
Playlist =
{
new PlaylistItem(CreateAPIBeatmapSet().Beatmaps.First())
{
RequiredMods = [new APIMod(new OsuModTraceable())],
AllowedMods = [new APIMod(new OsuModDoubleTime())]
}
},
EndDate = { Value = DateTimeOffset.Now.AddHours(12) },
Category = { Value = RoomCategory.DailyChallenge }
};

AddStep("add room", () => API.Perform(new CreateRoomRequest(room)));
AddStep("set daily challenge info", () => metadataClient.DailyChallengeInfo.Value = new DailyChallengeInfo { RoomID = 1234 });
AddStep("push screen", () => LoadScreen(new Screens.OnlinePlay.DailyChallenge.DailyChallenge(room)));
AddStep("daily challenge ended", () => metadataClient.DailyChallengeInfo.Value = null);
AddStep("install custom handler", () =>
{
((DummyAPIAccess)API).HandleRequest = req =>
{
switch (req)
{
case GetRoomRequest r:
{
r.TriggerSuccess(new Room
{
RoomID = { Value = 1235, },
Name = { Value = "Daily Challenge: June 5, 2024" },
Playlist =
{
new PlaylistItem(CreateAPIBeatmapSet().Beatmaps.First())
{
RequiredMods = [new APIMod(new OsuModTraceable())],
AllowedMods = [new APIMod(new OsuModDoubleTime())]
}
},
EndDate = { Value = DateTimeOffset.Now.AddHours(12) },
Category = { Value = RoomCategory.DailyChallenge }
});
return true;
}

default:
return false;
}
};
});
AddStep("next daily challenge started", () => metadataClient.DailyChallengeInfo.Value = new DailyChallengeInfo { RoomID = 1235 });
}
}
}
33 changes: 33 additions & 0 deletions osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
using osu.Game.Online.Multiplayer;
using osu.Game.Online.Rooms;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.OnlinePlay.Components;
Expand All @@ -54,6 +55,7 @@
private readonly Bindable<IReadOnlyList<Mod>> userMods = new Bindable<IReadOnlyList<Mod>>(Array.Empty<Mod>());

private readonly IBindable<APIState> apiState = new Bindable<APIState>();
private readonly IBindable<DailyChallengeInfo?> dailyChallengeInfo = new Bindable<DailyChallengeInfo?>();

private OnlinePlayScreenWaveContainer waves = null!;
private DailyChallengeLeaderboard leaderboard = null!;
Expand All @@ -65,6 +67,8 @@
private DailyChallengeTotalsDisplay totals = null!;
private DailyChallengeEventFeed feed = null!;

private SimpleNotification? waitForNextChallengeNotification;

[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Plum);

Expand Down Expand Up @@ -98,6 +102,9 @@
[Resolved]
private PreviewTrackManager previewTrackManager { get; set; } = null!;

[Resolved]
private INotificationOverlay? notificationOverlay { get; set; }

public override bool DisallowExternalBeatmapRulesetChanges => true;

public override bool? ApplyModTrackAdjustments => true;
Expand Down Expand Up @@ -336,6 +343,7 @@
}

metadataClient.MultiplayerRoomScoreSet += onRoomScoreSet;
dailyChallengeInfo.BindTo(metadataClient.DailyChallengeInfo);

((IBindable<MultiplayerScore?>)breakdown.UserBestScore).BindTo(leaderboard.UserBestScore);
}
Expand Down Expand Up @@ -388,6 +396,8 @@

apiState.BindTo(API.State);
apiState.BindValueChanged(onlineStateChanged, true);

dailyChallengeInfo.BindValueChanged(dailyChallengeChanged);
}

private void trySetDailyChallengeBeatmap()
Expand All @@ -405,6 +415,29 @@
Schedule(forcefullyExit);
});

private void dailyChallengeChanged(ValueChangedEvent<DailyChallengeInfo?> change)
{
if (change.OldValue?.RoomID == room.RoomID.Value && change.NewValue == null)
{
notificationOverlay?.Post(waitForNextChallengeNotification = new SimpleNotification
{
Text = "Today's daily challenge has concluded. Thanks for playing! The next one should appear in a few minutes."
});
}

if (change.NewValue != null && change.NewValue.Value.RoomID != room.RoomID.Value)
{
var roomRequest = new GetRoomRequest(change.NewValue.Value.RoomID);

roomRequest.Success += room =>
{
waitForNextChallengeNotification?.Close(false);
notificationOverlay?.Post(new NewDailyChallengeNotification(room));
};
API.Queue(roomRequest);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts on having this notification appear even if you aren't on the daily challenge screen?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See last line of OP:

The notifications are constrained to the daily challenge screen only to not spam users who may not care.

I'd rather avoid accusations of us 'railroading' users into this feature, but maybe I'm overly sensitive.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fair i guess. we'll see if people request it :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe only show for those who participated?

The current behavior doesn't work for people who log in straight at 0 UTC, when the button doesn't show.

Copy link
Member

@peppy peppy Jul 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm honestly thinking the vast majority of users are not going to be annoyed by a notification once a day at a specific time of day and we should just go for it and wait for complaints, rather than the other way around.

Obviously only for the "new daily challenge" notification, not the other one.

I'm also fine with a toggle for this being added, something like "Receive notifications for game-wide events"

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok well I'll have a go I guess, although now that I think about it figuring out a place to put the notification logic may prove to be a right pain in the ass.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done this in 1b57a2a. No toggle for now unless you think it is imperative for one to exist.

Not sure you'll like the placement, but it does work globally because of some implementation details (even if the button is offscreen, the bindable change callbacks fire, because that stuff is being invoked from MetadataClient which is everpresent).

}
}

private void forcefullyExit()
{
Logger.Log($"{this} forcefully exiting due to loss of API connection");
Expand Down Expand Up @@ -435,7 +468,7 @@
}

MultiplayerPlaylistItemStats[] stats = t.GetResultSafely();
var itemStats = stats.SingleOrDefault(item => item.PlaylistItemID == playlistItem.ID);

Check failure on line 471 in osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs

View workflow job for this annotation

GitHub Actions / Test Results (Linux, MultiThreaded)

osu.Game.Tests.Visual.DailyChallenge.TestSceneDailyChallenge ► TestNotifications

Failed test found in: TestResults-Linux-MultiThreaded.trx Error: System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.) ----> System.NullReferenceException : Object reference not set to an instance of an object.
Raw output
System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.)
  ----> System.NullReferenceException : Object reference not set to an instance of an object.
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at osu.Framework.Extensions.TaskExtensions.WaitSafely(Task task)
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--NullReferenceException
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_2(MultiplayerPlaylistItemStats item) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_0(Task`1 t) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at osu.Framework.Testing.TestScene.<>c__DisplayClass50_0.<SetupGameHostForNUnit>b__0()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Check failure on line 471 in osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs

View workflow job for this annotation

GitHub Actions / Test Results (Linux, MultiThreaded)

osu.Game.Tests.Visual.DailyChallenge.TestSceneDailyChallengeCarousel ► TestBasicAppearance

Failed test found in: TestResults-Linux-MultiThreaded.trx Error: System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.) ----> System.NullReferenceException : Object reference not set to an instance of an object.
Raw output
System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.)
  ----> System.NullReferenceException : Object reference not set to an instance of an object.
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--NullReferenceException
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_2(MultiplayerPlaylistItemStats item) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_0(Task`1 t) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at osu.Framework.Testing.TestScene.<>c__DisplayClass50_0.<SetupGameHostForNUnit>b__0()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Check failure on line 471 in osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs

View workflow job for this annotation

GitHub Actions / Test Results (Linux, MultiThreaded)

osu.Game.Tests.Visual.DailyChallenge.TestSceneDailyChallengeCarousel ► TestConstructor

Failed test found in: TestResults-Linux-MultiThreaded.trx Error: System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.) ----> System.NullReferenceException : Object reference not set to an instance of an object.
Raw output
System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.)
  ----> System.NullReferenceException : Object reference not set to an instance of an object.
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at osu.Framework.Extensions.TaskExtensions.WaitSafely(Task task)
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--NullReferenceException
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_2(MultiplayerPlaylistItemStats item) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_0(Task`1 t) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at osu.Framework.Testing.TestScene.<>c__DisplayClass50_0.<SetupGameHostForNUnit>b__0()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)

Check failure on line 471 in osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs

View workflow job for this annotation

GitHub Actions / Test Results (Linux, MultiThreaded)

osu.Game.Tests.Visual.DailyChallenge.TestSceneDailyChallengeCarousel ► TestIntegration

Failed test found in: TestResults-Linux-MultiThreaded.trx Error: System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.) ----> System.NullReferenceException : Object reference not set to an instance of an object.
Raw output
System.AggregateException : One or more errors occurred. (Object reference not set to an instance of an object.)
  ----> System.NullReferenceException : Object reference not set to an instance of an object.
   at osu.Framework.Testing.TestScene.UseTestSceneRunnerAttribute.AfterTest(ITest test)
   at NUnit.Framework.Internal.Commands.TestActionCommand.<>c__DisplayClass0_0.<.ctor>b__1(TestExecutionContext context)
   at NUnit.Framework.Internal.Commands.BeforeAndAfterTestCommand.<>c__DisplayClass1_0.<Execute>b__1()
   at NUnit.Framework.Internal.Commands.DelegatingTestCommand.RunTestMethodInThreadAbortSafeZone(TestExecutionContext context, Action action)
--NullReferenceException
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_2(MultiplayerPlaylistItemStats item) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Linq.Enumerable.TryGetSingle[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
   at osu.Game.Screens.OnlinePlay.DailyChallenge.DailyChallenge.<OnEntering>b__70_0(Task`1 t) in /home/runner/work/osu/osu/osu.Game/Screens/OnlinePlay/DailyChallenge/DailyChallenge.cs:line 471
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at osu.Framework.Platform.GameHost.<>c__DisplayClass141_0.<abortExecutionFromException>b__0()
   at osu.Framework.Threading.ScheduledDelegate.RunTaskInternal()
   at osu.Framework.Threading.Scheduler.Update()
   at osu.Framework.Threading.GameThread.processFrame()
   at osu.Framework.Platform.ThreadRunner.RunMainLoop()
   at osu.Framework.Platform.GameHost.windowUpdate()
   at osu.Framework.Platform.GameHost.Run(Game game)
   at osu.Framework.Testing.TestScene.<>c__DisplayClass50_0.<SetupGameHostForNUnit>b__0()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
if (itemStats == null) return;

Schedule(() =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// 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 osu.Framework.Allocation;
using osu.Framework.Screens;
using osu.Game.Beatmaps.Drawables.Cards;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Rooms;
using osu.Game.Overlays.Notifications;
using osu.Game.Screens.Menu;

namespace osu.Game.Screens.OnlinePlay.DailyChallenge
{
public partial class NewDailyChallengeNotification : SimpleNotification
{
private readonly Room room;

private BeatmapCardNano card = null!;

public NewDailyChallengeNotification(Room room)
{
this.room = room;
}

[BackgroundDependencyLoader]
private void load(OsuGame? game)
{
Text = "Today's daily challenge is here! Click here to play.";
Content.Add(card = new BeatmapCardNano((APIBeatmapSet)room.Playlist.Single().Beatmap.BeatmapSet!));
Activated = () =>
{
game?.PerformFromScreen(s => s.Push(new DailyChallenge(room)), [typeof(MainMenu)]);
return true;
};
}

protected override void Update()
{
base.Update();
card.Width = Content.DrawWidth;
}
}
}
2 changes: 1 addition & 1 deletion osu.Game/Tests/Visual/Metadata/TestMetadataClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public partial class TestMetadataClient : MetadataClient
public override IBindableDictionary<int, UserPresence> UserStates => userStates;
private readonly BindableDictionary<int, UserPresence> userStates = new BindableDictionary<int, UserPresence>();

public override IBindable<DailyChallengeInfo?> DailyChallengeInfo => dailyChallengeInfo;
public override Bindable<DailyChallengeInfo?> DailyChallengeInfo => dailyChallengeInfo;
private readonly Bindable<DailyChallengeInfo?> dailyChallengeInfo = new Bindable<DailyChallengeInfo?>();

[Resolved]
Expand Down
Loading