feat(desktop): sort and show status in friend list

This commit is contained in:
Anna 2020-11-14 15:08:48 -05:00
parent 358010d6e0
commit e0b093df4d
16 changed files with 176 additions and 10 deletions

View File

@ -303,9 +303,12 @@ namespace XIVChat_Desktop {
var playerList = ServerPlayerList.Decode(payload);
if (playerList.Type == PlayerListType.Friend) {
var players = playerList.Players
.OrderBy(player => !player.HasStatus(PlayerStatus.Online));
this.app.Dispatch(() => {
this.app.Window.FriendList.Clear();
foreach (var player in playerList.Players) {
foreach (var player in players) {
this.app.Window.FriendList.Add(player);
}
});

View File

@ -5,6 +5,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XIVChat_Desktop"
xmlns:ui="http://schemas.modernwpf.com/2019"
xmlns:common="clr-namespace:XIVChatCommon;assembly=XIVChatCommon"
ui:WindowHelper.UseModernWindowStyle="True"
mc:Ignorable="d"
Title="Friend list"
@ -30,7 +31,20 @@
IsReadOnly="True"
CanUserReorderColumns="True"
Visibility="{Binding Waiting, Converter={StaticResource InverseBoolToVisibilityConverter}}">
<DataGrid.Resources>
<local:FriendListStatusConverter x:Key="StatusConverter" />
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTemplateColumn d:DataContext="{d:DesignInstance common:Player}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image MaxHeight="32"
MaxWidth="32"
Margin="4"
Source="{Binding ., Converter={StaticResource StatusConverter}}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Name"
Binding="{Binding Name}" />
<DataGridTextColumn Header="Job"

View File

@ -1,8 +1,12 @@
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using XIVChatCommon;
namespace XIVChat_Desktop {
public partial class FriendList : INotifyPropertyChanged {
@ -51,4 +55,75 @@ namespace XIVChat_Desktop {
this.App.Window.FriendList.CollectionChanged -= this.OnFriendListChanged;
}
}
public class FriendListStatusConverter : IValueConverter {
private static readonly BitmapFrame ImageOnline = ImageOf("app_status_online");
private static readonly BitmapFrame ImageOffline = ImageOf("app_status_offline");
private static readonly BitmapFrame ImageAfk = ImageOf("app_status_afk");
private static readonly BitmapFrame ImageContents = ImageOf("app_status_contents");
private static readonly BitmapFrame ImageContentsSimilar = ImageOf("app_status_contents_similar");
private static readonly BitmapFrame ImageContentsSame = ImageOf("app_status_contents_same");
private static readonly BitmapFrame ImageCrossPartyLeader = ImageOf("app_status_cross_party_leader");
private static readonly BitmapFrame ImageCrossPartyMember = ImageOf("app_status_cross_party_member");
private static readonly BitmapFrame ImagePartyLeader = ImageOf("app_status_party_leader");
private static readonly BitmapFrame ImagePartyMember = ImageOf("app_status_party_member");
private static readonly BitmapFrame ImageRoleplaying = ImageOf("app_status_roleplaying");
private static BitmapFrame ImageOf(string file) {
var uri = $"pack://application:,,,/Resources/status/{file}.png";
return BitmapFrame.Create(new Uri(uri));
}
public object? Convert(object? value, Type targetType, object parameter, CultureInfo culture) {
if (!(value is Player player)) {
return null;
}
if (player.HasStatus(PlayerStatus.SharingDuty)) {
return ImageContentsSame;
}
if (player.HasStatus(PlayerStatus.SimilarDuty)) {
return ImageContentsSimilar;
}
if (player.HasStatus(PlayerStatus.AnotherWorld)) {
return ImageContents;
}
if (player.HasStatus(PlayerStatus.AwayFromKeyboard)) {
return ImageAfk;
}
if (player.HasStatus(PlayerStatus.RolePlaying)) {
return ImageRoleplaying;
}
if (player.HasStatus(PlayerStatus.PartyLeaderCrossWorld)) {
return ImageCrossPartyLeader;
}
if (player.HasStatus(PlayerStatus.PartyMemberCrossWorld)) {
return ImageCrossPartyMember;
}
if (player.HasStatus(PlayerStatus.PartyLeader)) {
return ImagePartyLeader;
}
if (player.HasStatus(PlayerStatus.PartyMember)) {
return ImagePartyMember;
}
if (player.HasStatus(PlayerStatus.Online)) {
return ImageOnline;
}
return ImageOffline;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
throw new NotImplementedException();
}
}
}

Binary file not shown.

Binary file not shown.

View File

@ -14,10 +14,38 @@
</PropertyGroup>
<ItemGroup>
<None Remove="fonts\ffxiv.ttf" />
<None Remove="ic_launcher-playstore.png" />
<None Remove="Resources\logo.ico" />
<None Remove="Resources\fonticon_ps4.tex.png" />
<None Remove="Resources\logo.ico" />
<None Remove="Resources\status\app_status_afk.png" />
<None Remove="Resources\status\app_status_contents.png" />
<None Remove="Resources\status\app_status_contents_same.png" />
<None Remove="Resources\status\app_status_contents_similar.png" />
<None Remove="Resources\status\app_status_cross_party_leader.png" />
<None Remove="Resources\status\app_status_cross_party_member.png" />
<None Remove="Resources\status\app_status_offline.png" />
<None Remove="Resources\status\app_status_online.png" />
<None Remove="Resources\status\app_status_party_leader.png" />
<None Remove="Resources\status\app_status_party_member.png" />
<None Remove="Resources\status\app_status_roleplaying.png" />
<None Remove="Resources\status\app_status_roleplaying.svg" />
<None Remove="fonts\ffxiv.ttf" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\fonticon_ps4.tex.png" />
<Resource Include="Resources\logo.ico" />
<Resource Include="Resources\status\app_status_afk.png" />
<Resource Include="Resources\status\app_status_contents.png" />
<Resource Include="Resources\status\app_status_contents_same.png" />
<Resource Include="Resources\status\app_status_contents_similar.png" />
<Resource Include="Resources\status\app_status_cross_party_leader.png" />
<Resource Include="Resources\status\app_status_cross_party_member.png" />
<Resource Include="Resources\status\app_status_offline.png" />
<Resource Include="Resources\status\app_status_online.png" />
<Resource Include="Resources\status\app_status_party_leader.png" />
<Resource Include="Resources\status\app_status_party_member.png" />
<Resource Include="Resources\status\app_status_roleplaying.png" />
<Resource Include="fonts\ffxiv.ttf" />
</ItemGroup>
<ItemGroup>
@ -31,12 +59,6 @@
<ProjectReference Include="..\XIVChatCommon\XIVChatCommon.csproj" />
</ItemGroup>
<ItemGroup>
<Resource Include="fonts\ffxiv.ttf" />
<Resource Include="Resources\fonticon_ps4.tex.png" />
<Resource Include="Resources\logo.ico" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>

View File

@ -1077,6 +1077,58 @@ namespace XIVChatCommon {
[Key(14)]
public byte MainLanguage { get; set; }
public bool HasStatus(PlayerStatus status) => (this.Status & ((ulong)1 << (int)status)) > 0;
}
public enum PlayerStatus {
GameQa = 1,
GameMaster1 = 2,
GameMaster2 = 3,
EventParticipant = 4,
Disconnected = 5,
WaitingForFriendListApproval = 6,
WaitingForLinkshellApproval = 7,
WaitingForFreeCompanyApproval = 8,
NotFound = 9,
Offline = 10,
BattleMentor = 11,
Busy = 12,
Pvp = 13,
PlayingTripleTriad = 14,
ViewingCutscene = 15,
UsingAChocoboPorter = 16,
AwayFromKeyboard = 17,
CameraMode = 18,
LookingForRepairs = 19,
LookingToRepair = 20,
LookingToMeldMateria = 21,
RolePlaying = 22,
LookingForParty = 23,
SwordForHire = 24,
WaitingForDutyFinder = 25,
RecruitingPartyMembers = 26,
Mentor = 27,
PveMentor = 28,
TradeMentor = 29,
PvpMentor = 30,
Returner = 31,
NewAdventurer = 32,
AllianceLeader = 33,
AlliancePartyLeader = 34,
AlliancePartyMember = 35,
PartyLeader = 36,
PartyMember = 37,
PartyLeaderCrossWorld = 38,
PartyMemberCrossWorld = 39,
AnotherWorld = 40,
SharingDuty = 41,
SimilarDuty = 42,
InDuty = 43,
TrialAdventurer = 44,
FreeCompany = 45,
GrandCompany = 46,
Online = 47,
}
[MessagePackObject]