2018-01-05 19:21:19 +08:00
|
|
|
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
|
2017-05-26 11:52:01 +08:00
|
|
|
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
|
|
|
|
|
2017-05-26 13:00:38 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
using System.Linq;
|
2017-06-07 19:05:43 +08:00
|
|
|
using osu.Framework.Allocation;
|
2017-05-26 13:00:38 +08:00
|
|
|
using OpenTK;
|
2017-05-26 11:52:01 +08:00
|
|
|
using OpenTK.Graphics;
|
2017-05-26 12:32:20 +08:00
|
|
|
using osu.Framework.Graphics;
|
2017-05-26 13:00:38 +08:00
|
|
|
using osu.Framework.Graphics.Containers;
|
2017-05-26 11:52:01 +08:00
|
|
|
using osu.Game.Graphics;
|
2017-06-12 15:40:53 +08:00
|
|
|
using osu.Game.Graphics.UserInterface;
|
2017-06-07 19:05:43 +08:00
|
|
|
using osu.Game.Online.API;
|
|
|
|
using osu.Game.Online.API.Requests;
|
2017-05-26 13:44:09 +08:00
|
|
|
using osu.Game.Overlays.SearchableList;
|
2017-05-26 11:52:01 +08:00
|
|
|
using osu.Game.Overlays.Social;
|
2017-05-26 13:00:38 +08:00
|
|
|
using osu.Game.Users;
|
2017-05-26 11:52:01 +08:00
|
|
|
|
|
|
|
namespace osu.Game.Overlays
|
|
|
|
{
|
2017-12-30 19:56:18 +08:00
|
|
|
public class SocialOverlay : SearchableListOverlay<SocialTab, SocialSortCriteria, SortDirection>, IOnlineComponent
|
2017-05-26 11:52:01 +08:00
|
|
|
{
|
2017-12-25 03:25:23 +08:00
|
|
|
private APIAccess api;
|
2018-01-04 00:54:20 +08:00
|
|
|
private readonly LoadingAnimation loading;
|
2018-01-04 18:41:06 +08:00
|
|
|
private FillFlowContainer<SocialPanel> panels;
|
2017-05-26 13:00:38 +08:00
|
|
|
|
2017-05-26 13:16:56 +08:00
|
|
|
protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b");
|
|
|
|
protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51");
|
|
|
|
protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"5c2648");
|
|
|
|
|
2017-05-26 13:44:09 +08:00
|
|
|
protected override SearchableListHeader<SocialTab> CreateHeader() => new Header();
|
2017-06-01 08:29:50 +08:00
|
|
|
protected override SearchableListFilterControl<SocialSortCriteria, SortDirection> CreateFilterControl() => new FilterControl();
|
2017-05-26 13:16:56 +08:00
|
|
|
|
2017-12-25 03:25:23 +08:00
|
|
|
private IEnumerable<User> users;
|
2017-05-26 13:00:38 +08:00
|
|
|
public IEnumerable<User> Users
|
|
|
|
{
|
|
|
|
get { return users; }
|
|
|
|
set
|
|
|
|
{
|
2017-12-25 03:25:23 +08:00
|
|
|
if (users?.Equals(value) ?? false)
|
|
|
|
return;
|
2017-05-26 13:00:38 +08:00
|
|
|
|
2017-12-25 03:25:23 +08:00
|
|
|
users = value?.ToList();
|
2017-05-26 13:00:38 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-26 12:32:20 +08:00
|
|
|
public SocialOverlay()
|
|
|
|
{
|
2017-05-28 05:35:46 +08:00
|
|
|
FirstWaveColour = OsuColour.FromHex(@"cb5fa0");
|
|
|
|
SecondWaveColour = OsuColour.FromHex(@"b04384");
|
|
|
|
ThirdWaveColour = OsuColour.FromHex(@"9b2b6e");
|
|
|
|
FourthWaveColour = OsuColour.FromHex(@"6d214d");
|
2017-05-26 13:55:25 +08:00
|
|
|
|
2017-12-25 03:25:23 +08:00
|
|
|
Add(loading = new LoadingAnimation());
|
|
|
|
|
2018-01-04 00:54:20 +08:00
|
|
|
Filter.Search.Current.ValueChanged += text =>
|
|
|
|
{
|
|
|
|
if (text != string.Empty)
|
|
|
|
{
|
|
|
|
Header.Tabs.Current.Value = SocialTab.Search;
|
|
|
|
|
|
|
|
if (Filter.Tabs.Current.Value == SocialSortCriteria.Rank)
|
|
|
|
Filter.Tabs.Current.Value = SocialSortCriteria.Relevance;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Header.Tabs.Current.Value = SocialTab.OnlinePlayers;
|
|
|
|
|
|
|
|
if (Filter.Tabs.Current.Value == SocialSortCriteria.Relevance)
|
|
|
|
Filter.Tabs.Current.Value = SocialSortCriteria.Rank;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-12-25 03:25:23 +08:00
|
|
|
Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels;
|
|
|
|
|
|
|
|
// TODO sort our list in some way (either locally or with API call)
|
2018-01-04 00:54:20 +08:00
|
|
|
//Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += sortOrder => Scheduler.AddOnce(updateSearch);
|
2017-12-25 03:25:23 +08:00
|
|
|
|
2018-01-04 00:54:20 +08:00
|
|
|
Header.Tabs.Current.ValueChanged += tab =>
|
|
|
|
{
|
|
|
|
if (tab != SocialTab.Search)
|
|
|
|
{
|
|
|
|
//currentQuery.Value = string.Empty;
|
|
|
|
Filter.Tabs.Current.Value = (SocialSortCriteria)Header.Tabs.Current.Value;
|
|
|
|
Scheduler.AddOnce(updateSearch);
|
|
|
|
}
|
|
|
|
};
|
2017-12-25 03:25:23 +08:00
|
|
|
|
2017-12-30 18:54:03 +08:00
|
|
|
//currentQuery.ValueChanged += v =>
|
|
|
|
//{
|
|
|
|
// queryChangedDebounce?.Cancel();
|
|
|
|
|
|
|
|
// if (string.IsNullOrEmpty(v))
|
|
|
|
// Scheduler.AddOnce(updateSearch);
|
|
|
|
// else
|
|
|
|
// queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500);
|
|
|
|
//};
|
2017-06-12 15:40:53 +08:00
|
|
|
|
2018-01-03 00:58:11 +08:00
|
|
|
//currentQuery.BindTo(Filter.Search.Current);
|
2017-12-25 03:25:23 +08:00
|
|
|
|
2018-01-04 00:54:20 +08:00
|
|
|
Filter.Tabs.Current.ValueChanged += sortCriteria =>
|
|
|
|
{
|
|
|
|
if (Header.Tabs.Current.Value != SocialTab.Search && sortCriteria != (SocialSortCriteria)Header.Tabs.Current.Value)
|
|
|
|
Header.Tabs.Current.Value = SocialTab.Search;
|
|
|
|
|
|
|
|
Scheduler.AddOnce(updateSearch);
|
|
|
|
};
|
2017-05-26 12:32:20 +08:00
|
|
|
}
|
2017-06-07 19:05:43 +08:00
|
|
|
|
|
|
|
[BackgroundDependencyLoader]
|
|
|
|
private void load(APIAccess api)
|
|
|
|
{
|
2017-12-25 03:25:23 +08:00
|
|
|
this.api = api;
|
2017-12-30 19:56:18 +08:00
|
|
|
api.Register(this);
|
2017-06-07 19:05:43 +08:00
|
|
|
}
|
|
|
|
|
2017-12-25 03:25:23 +08:00
|
|
|
private void recreatePanels(PanelDisplayStyle displayStyle)
|
2017-06-07 19:05:43 +08:00
|
|
|
{
|
2018-01-03 00:42:44 +08:00
|
|
|
clearPanels();
|
2017-12-25 03:25:23 +08:00
|
|
|
|
2017-12-25 21:17:35 +08:00
|
|
|
if (Users == null)
|
|
|
|
return;
|
|
|
|
|
2018-01-04 18:41:06 +08:00
|
|
|
var newPanels = new FillFlowContainer<SocialPanel>
|
2017-12-25 03:25:23 +08:00
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.X,
|
|
|
|
AutoSizeAxes = Axes.Y,
|
|
|
|
Spacing = new Vector2(10f),
|
|
|
|
Margin = new MarginPadding { Top = 10 },
|
|
|
|
ChildrenEnumerable = Users.Select(u =>
|
|
|
|
{
|
2018-01-04 18:41:06 +08:00
|
|
|
SocialPanel panel;
|
2017-12-25 03:25:23 +08:00
|
|
|
switch (displayStyle)
|
|
|
|
{
|
|
|
|
case PanelDisplayStyle.Grid:
|
2018-01-04 18:41:06 +08:00
|
|
|
panel = new SocialGridPanel(u)
|
|
|
|
{
|
|
|
|
Anchor = Anchor.TopCentre,
|
|
|
|
Origin = Anchor.TopCentre
|
|
|
|
};
|
2017-12-25 03:25:23 +08:00
|
|
|
break;
|
|
|
|
default:
|
2018-01-04 18:41:06 +08:00
|
|
|
panel = new SocialListPanel(u);
|
2017-12-25 03:25:23 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
panel.Status.BindTo(u.Status);
|
|
|
|
return panel;
|
|
|
|
})
|
2017-06-12 15:40:53 +08:00
|
|
|
};
|
|
|
|
|
2018-01-04 18:41:06 +08:00
|
|
|
LoadComponentAsync(newPanels, p =>
|
|
|
|
{
|
|
|
|
if(panels != null)
|
|
|
|
ScrollFlow.Remove(panels);
|
|
|
|
|
2018-01-06 17:40:18 +08:00
|
|
|
Scheduler.AddDelayed(() => ScrollFlow.Add(panels = newPanels), 200);
|
2018-01-04 18:41:06 +08:00
|
|
|
});
|
2017-06-07 19:05:43 +08:00
|
|
|
}
|
|
|
|
|
2018-01-03 00:42:44 +08:00
|
|
|
private void clearPanels()
|
|
|
|
{
|
|
|
|
if (panels != null)
|
|
|
|
{
|
2018-01-04 18:41:06 +08:00
|
|
|
panels.FadeOut(200);
|
2018-01-03 00:42:44 +08:00
|
|
|
panels.Expire();
|
|
|
|
panels = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-30 18:51:49 +08:00
|
|
|
private APIRequest getUsersRequest;
|
2017-12-25 03:25:23 +08:00
|
|
|
|
2018-01-03 00:58:11 +08:00
|
|
|
//private readonly Bindable<string> currentQuery = new Bindable<string>();
|
2017-12-25 03:25:23 +08:00
|
|
|
|
2018-01-03 00:58:11 +08:00
|
|
|
//private ScheduledDelegate queryChangedDebounce;
|
2017-12-25 03:25:23 +08:00
|
|
|
|
|
|
|
private void updateSearch()
|
2017-06-07 19:05:43 +08:00
|
|
|
{
|
2018-01-03 00:58:11 +08:00
|
|
|
//queryChangedDebounce?.Cancel();
|
2017-12-25 03:25:23 +08:00
|
|
|
|
|
|
|
if (!IsLoaded)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Users = null;
|
2018-01-03 00:42:44 +08:00
|
|
|
clearPanels();
|
2017-12-25 03:25:23 +08:00
|
|
|
loading.Hide();
|
2017-12-30 18:51:49 +08:00
|
|
|
getUsersRequest?.Cancel();
|
2017-12-25 03:25:23 +08:00
|
|
|
|
2018-01-03 00:42:44 +08:00
|
|
|
if (api?.IsLoggedIn == false)
|
2017-12-25 03:25:23 +08:00
|
|
|
return;
|
|
|
|
|
2017-12-29 02:32:06 +08:00
|
|
|
switch (Header.Tabs.Current.Value)
|
|
|
|
{
|
|
|
|
case SocialTab.OnlineFriends:
|
2018-01-04 18:41:06 +08:00
|
|
|
var friendRequest = new GetFriendsRequest();
|
2018-01-03 00:22:12 +08:00
|
|
|
friendRequest.Success += updateUsers;
|
2018-01-03 00:18:49 +08:00
|
|
|
api.Queue(getUsersRequest = friendRequest);
|
2017-12-29 02:32:06 +08:00
|
|
|
break;
|
2018-01-04 00:54:20 +08:00
|
|
|
default:
|
|
|
|
var userRequest = new GetUsersRequest(); // TODO filter???
|
|
|
|
userRequest.Success += response => updateUsers(response.Select(r => r.User));
|
|
|
|
api.Queue(getUsersRequest = userRequest);
|
|
|
|
break;
|
2017-12-29 02:32:06 +08:00
|
|
|
}
|
|
|
|
loading.Show();
|
|
|
|
}
|
|
|
|
|
2018-01-03 00:22:12 +08:00
|
|
|
private void updateUsers(IEnumerable<User> newUsers)
|
2017-12-29 02:32:06 +08:00
|
|
|
{
|
2018-01-03 00:22:12 +08:00
|
|
|
Schedule(() =>
|
2017-06-07 19:05:43 +08:00
|
|
|
{
|
2018-01-03 00:22:12 +08:00
|
|
|
Users = newUsers;
|
|
|
|
loading.Hide();
|
2018-01-03 00:42:44 +08:00
|
|
|
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
|
2017-12-29 02:32:06 +08:00
|
|
|
});
|
2017-06-07 19:05:43 +08:00
|
|
|
}
|
2017-12-30 19:56:18 +08:00
|
|
|
|
|
|
|
public void APIStateChanged(APIAccess api, APIState state)
|
|
|
|
{
|
|
|
|
switch (state)
|
|
|
|
{
|
|
|
|
case APIState.Online:
|
|
|
|
Scheduler.AddOnce(updateSearch);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
Users = null;
|
|
|
|
recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-05-26 11:52:01 +08:00
|
|
|
}
|
|
|
|
|
2017-05-26 12:32:20 +08:00
|
|
|
public enum SortDirection
|
2017-05-26 11:52:01 +08:00
|
|
|
{
|
2017-06-07 19:05:43 +08:00
|
|
|
Ascending,
|
2018-01-04 00:53:50 +08:00
|
|
|
Descending
|
2017-05-26 11:52:01 +08:00
|
|
|
}
|
|
|
|
}
|