1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-04 09:03:54 +08:00

Handle stream counts internally

This commit is contained in:
Dan Balasescu
2025-03-13 01:36:24 +09:00
Unverified
parent 0906983f6f
commit 9ff6c44559
2 changed files with 59 additions and 52 deletions
@@ -1,7 +1,6 @@
// 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.Collections.Specialized;
using System.Linq;
using System.Threading;
using osu.Framework.Allocation;
@@ -12,23 +11,17 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics.UserInterface;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Metadata;
using osu.Game.Resources.Localisation.Web;
using osu.Game.Users;
namespace osu.Game.Overlays.Dashboard.Friends
{
public partial class FriendDisplay : CompositeDrawable
{
private readonly IBindableList<APIRelation> apiFriends = new BindableList<APIRelation>();
private readonly IBindableDictionary<int, UserPresence> friendPresences = new BindableDictionary<int, UserPresence>();
[Resolved]
private IAPIProvider api { get; set; } = null!;
[Resolved]
private MetadataClient metadataClient { get; set; } = null!;
private FriendOnlineStreamControl streamControl = null!;
private Box background = null!;
private Box controlBackground = null!;
@@ -170,31 +163,11 @@ namespace osu.Game.Overlays.Dashboard.Friends
base.LoadComplete();
apiFriends.BindTo(api.Friends);
apiFriends.BindCollectionChanged(onFriendsChanged, true);
friendPresences.BindTo(metadataClient.FriendPresences);
friendPresences.BindCollectionChanged(onFriendPresencesChanged, true);
apiFriends.BindCollectionChanged((_, _) => reloadList());
userListToolbar.DisplayStyle.BindValueChanged(_ => reloadList());
}
private void onFriendsChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
reloadList();
updateStatusCounts();
}
private void onFriendPresencesChanged(object? sender, NotifyDictionaryChangedEventArgs<int, UserPresence> e)
{
switch (e.Action)
{
case NotifyDictionaryChangedAction.Add:
case NotifyDictionaryChangedAction.Remove:
updateStatusCounts();
break;
}
}
private void reloadList()
{
listLoadCancellation?.Cancel();
@@ -225,23 +198,5 @@ namespace osu.Game.Overlays.Dashboard.Friends
newList.FadeIn(200, Easing.OutQuint);
}
}
private void updateStatusCounts()
{
int countOnline = 0;
int countOffline = 0;
foreach (var user in apiFriends)
{
if (friendPresences.ContainsKey(user.TargetID))
countOnline++;
else
countOffline++;
}
streamControl.CountAll.Value = apiFriends.Count;
streamControl.CountOnline.Value = countOnline;
streamControl.CountOffline.Value = countOffline;
}
}
}
@@ -2,15 +2,28 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Online.Metadata;
using osu.Game.Users;
namespace osu.Game.Overlays.Dashboard.Friends
{
public partial class FriendOnlineStreamControl : OverlayStreamControl<OnlineStatus>
{
public readonly BindableInt CountAll = new BindableInt();
public readonly BindableInt CountOnline = new BindableInt();
public readonly BindableInt CountOffline = new BindableInt();
private readonly IBindableDictionary<int, UserPresence> friendPresences = new BindableDictionary<int, UserPresence>();
private readonly IBindableList<APIRelation> apiFriends = new BindableList<APIRelation>();
private readonly BindableInt countAll = new BindableInt();
private readonly BindableInt countOnline = new BindableInt();
private readonly BindableInt countOffline = new BindableInt();
[Resolved]
private IAPIProvider api { get; set; } = null!;
[Resolved]
private MetadataClient metadataClient { get; set; } = null!;
public FriendOnlineStreamControl()
{
@@ -22,18 +35,57 @@ namespace osu.Game.Overlays.Dashboard.Friends
];
}
protected override void LoadComplete()
{
base.LoadComplete();
apiFriends.BindTo(api.Friends);
apiFriends.BindCollectionChanged((_, _) => updateCounts());
friendPresences.BindTo(metadataClient.FriendPresences);
friendPresences.BindCollectionChanged(onFriendPresencesChanged);
updateCounts();
}
private void onFriendPresencesChanged(object? sender, NotifyDictionaryChangedEventArgs<int, UserPresence> e)
{
switch (e.Action)
{
case NotifyDictionaryChangedAction.Add:
case NotifyDictionaryChangedAction.Remove:
updateCounts();
break;
}
}
private void updateCounts()
{
countAll.Value = apiFriends.Count;
countOnline.Value = 0;
countOffline.Value = 0;
foreach (var user in apiFriends)
{
if (friendPresences.ContainsKey(user.TargetID))
countOnline.Value++;
else
countOffline.Value++;
}
}
protected override OverlayStreamItem<OnlineStatus> CreateStreamItem(OnlineStatus value)
{
switch (value)
{
case OnlineStatus.All:
return new FriendsOnlineStatusItem(value) { UserCount = { BindTarget = CountAll } };
return new FriendsOnlineStatusItem(value) { UserCount = { BindTarget = countAll } };
case OnlineStatus.Online:
return new FriendsOnlineStatusItem(value) { UserCount = { BindTarget = CountOnline } };
return new FriendsOnlineStatusItem(value) { UserCount = { BindTarget = countOnline } };
case OnlineStatus.Offline:
return new FriendsOnlineStatusItem(value) { UserCount = { BindTarget = CountOffline } };
return new FriendsOnlineStatusItem(value) { UserCount = { BindTarget = countOffline } };
default:
throw new ArgumentException(nameof(value));