diff --git a/osu.Game/Online/Leaderboards/Leaderboard.cs b/osu.Game/Online/Leaderboards/Leaderboard.cs index a426d2b448..d843dcb2bb 100644 --- a/osu.Game/Online/Leaderboards/Leaderboard.cs +++ b/osu.Game/Online/Leaderboards/Leaderboard.cs @@ -139,6 +139,139 @@ namespace osu.Game.Online.Leaderboards } } + protected Leaderboard() + { + InternalChildren = new Drawable[] + { + new OsuContextMenuContainer + { + RelativeSizeAxes = Axes.Both, + Masking = true, + Child = new GridContainer + { + RelativeSizeAxes = Axes.Both, + RowDimensions = new[] + { + new Dimension(), + new Dimension(GridSizeMode.AutoSize), + }, + Content = new[] + { + new Drawable[] + { + scrollContainer = new OsuScrollContainer + { + RelativeSizeAxes = Axes.Both, + ScrollbarVisible = false, + } + }, + new Drawable[] + { + new Container + { + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, + Child = topScoreContainer = new UserTopScoreContainer(CreateDrawableTopScore) + }, + }, + }, + }, + }, + loading = new LoadingSpinner(), + placeholderContainer = new Container + { + RelativeSizeAxes = Axes.Both + }, + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (api != null) + { + apiState.BindTo(api.State); + apiState.BindValueChanged(state => + { + switch (state.NewValue) + { + case APIState.Online: + case APIState.Offline: + if (IsOnlineScope) + RefetchScores(); + + break; + } + }); + } + + RefetchScores(); + } + + public void RefetchScores() => Scheduler.AddOnce(refetchScores); + + protected virtual void Reset() + { + cancelPendingWork(); + Scores = null; + } + + /// + /// Performs a fetch/refresh of scores to be displayed. + /// + /// A callback which should be called when fetching is completed. Scheduling is not required. + /// An responsible for the fetch operation. This will be queued and performed automatically. + protected abstract APIRequest FetchScores(Action> scoresCallback); + + protected abstract LeaderboardScore CreateDrawableScore(TScoreInfo model, int index); + + protected abstract LeaderboardScore CreateDrawableTopScore(TScoreInfo model); + + private void refetchScores() + { + // don't display any scores or placeholder until the first Scores_Set has been called. + // this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished. + if (!scoresLoadedOnce) return; + + cancelPendingWork(); + + PlaceholderState = PlaceholderState.Retrieving; + loading.Show(); + + getScoresRequest = FetchScores(scores => getScoresRequestCallback = Schedule(() => + { + Scores = scores.ToArray(); + PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; + })); + + if (getScoresRequest == null) + return; + + getScoresRequest.Failure += e => getScoresRequestCallback = Schedule(() => + { + if (e is OperationCanceledException) + return; + + PlaceholderState = PlaceholderState.NetworkFailure; + }); + + api?.Queue(getScoresRequest); + } + + private void cancelPendingWork() + { + getScoresRequest?.Cancel(); + getScoresRequest = null; + + getScoresRequestCallback?.Cancel(); + getScoresRequestCallback = null; + } + + #region Placeholder handling + + private Placeholder currentPlaceholder; + private PlaceholderState placeholderState; /// @@ -194,133 +327,6 @@ namespace osu.Game.Online.Leaderboards } } - protected Leaderboard() - { - InternalChildren = new Drawable[] - { - new OsuContextMenuContainer - { - RelativeSizeAxes = Axes.Both, - Masking = true, - Child = new GridContainer - { - RelativeSizeAxes = Axes.Both, - RowDimensions = new[] - { - new Dimension(), - new Dimension(GridSizeMode.AutoSize), - }, - Content = new[] - { - new Drawable[] - { - scrollContainer = new OsuScrollContainer - { - RelativeSizeAxes = Axes.Both, - ScrollbarVisible = false, - } - }, - new Drawable[] - { - new Container - { - AutoSizeAxes = Axes.Y, - RelativeSizeAxes = Axes.X, - Child = topScoreContainer = new UserTopScoreContainer(CreateDrawableTopScore) - }, - }, - }, - }, - }, - loading = new LoadingSpinner(), - placeholderContainer = new Container - { - RelativeSizeAxes = Axes.Both - }, - }; - } - - protected virtual void Reset() - { - cancelPendingWork(); - Scores = null; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - if (api != null) - { - apiState.BindTo(api.State); - apiState.BindValueChanged(state => - { - switch (state.NewValue) - { - case APIState.Online: - case APIState.Offline: - if (IsOnlineScope) - RefetchScores(); - - break; - } - }); - } - - RefetchScores(); - } - - public void RefetchScores() => Scheduler.AddOnce(refetchScores); - - private void refetchScores() - { - // don't display any scores or placeholder until the first Scores_Set has been called. - // this avoids scope changes flickering a "no scores" placeholder before initialisation of song select is finished. - if (!scoresLoadedOnce) return; - - cancelPendingWork(); - - PlaceholderState = PlaceholderState.Retrieving; - loading.Show(); - - getScoresRequest = FetchScores(scores => getScoresRequestCallback = Schedule(() => - { - Scores = scores.ToArray(); - PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; - })); - - if (getScoresRequest == null) - return; - - getScoresRequest.Failure += e => getScoresRequestCallback = Schedule(() => - { - if (e is OperationCanceledException) - return; - - PlaceholderState = PlaceholderState.NetworkFailure; - }); - - api?.Queue(getScoresRequest); - } - - private void cancelPendingWork() - { - getScoresRequest?.Cancel(); - getScoresRequest = null; - - getScoresRequestCallback?.Cancel(); - getScoresRequestCallback = null; - } - - /// - /// Performs a fetch/refresh of scores to be displayed. - /// - /// A callback which should be called when fetching is completed. Scheduling is not required. - /// An responsible for the fetch operation. This will be queued and performed automatically. - protected abstract APIRequest FetchScores(Action> scoresCallback); - - private Placeholder currentPlaceholder; - private void replacePlaceholder(Placeholder placeholder) { if (placeholder != null && placeholder.Equals(currentPlaceholder)) @@ -342,6 +348,10 @@ namespace osu.Game.Online.Leaderboards currentPlaceholder = placeholder; } + #endregion + + #region Fade handling + protected override void UpdateAfterChildren() { base.UpdateAfterChildren(); @@ -384,8 +394,6 @@ namespace osu.Game.Online.Leaderboards } } - protected abstract LeaderboardScore CreateDrawableScore(TScoreInfo model, int index); - - protected abstract LeaderboardScore CreateDrawableTopScore(TScoreInfo model); + #endregion } }