Commit df3e8c39 authored by HankG's avatar HankG

Add sorting and filtering of People List

parent cd9cc8c0
using System;
using System.Collections.Generic;
using MySocialPortalDesktop.ViewModels;
namespace MySocialPortalDesktop.Comparer
{
public class PersonViewModelComparer : IComparer<PersonViewModel>
{
private readonly int _multiplier;
private readonly SortFieldEnum _sortField;
public PersonViewModelComparer():this(true, SortFieldEnum.DisplayName)
{
}
public PersonViewModelComparer(bool increasing, SortFieldEnum sortOn)
{
if(increasing)
{
_multiplier = 1;
}
else
{
_multiplier = -1;
}
_sortField = sortOn;
}
public int Compare(PersonViewModel x, PersonViewModel y)
{
if (x == null || y == null)
{
return 0;
}
if(_sortField == SortFieldEnum.DisplayName)
{
return _multiplier * string.Compare(x.DisplayName, y.DisplayName, StringComparison.Ordinal);
}
return _multiplier * string.Compare(x.DisplayUsername, y.DisplayUsername, StringComparison.Ordinal);
}
public enum SortFieldEnum
{
DisplayName,
DisplayUsername
}
}
}
\ No newline at end of file
using System;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Media.Imaging;
using JetBrains.Annotations;
using MySocialPortalDesktop.Factory;
using MySocialPortalDesktop.Services;
using MySocialPortalLib.Model;
namespace MySocialPortalDesktop.Util
{
public static class PersonDataGenerator
{
public static async Task<string> GetDefaultUserName(Person person)
{
const string unknownValue = "N/A";
const string screenNameKey = "ScreenName";
if (person == null)
{
return unknownValue;
}
var screenName = "";
person.SocialMediaAccounts[StandardSocialNetworkNames.Twitter]
?.AdditionalProperties.TryGetValue(screenNameKey, out screenName);
return string.IsNullOrWhiteSpace(screenName) ? unknownValue : screenName;
}
public static async Task<Bitmap> LoadProfileImage(Person person)
{
if (person == null)
{
return DefaultValueService.DefaultProfileImage;
}
var profileImageUrl = person.SocialMediaAccounts.First().Value.ProfilePhotoPath;
try
{
if (!string.IsNullOrWhiteSpace(profileImageUrl))
{
var (found, imageFileInfo) = await ServiceFactory.Instance.ProfileImageService
.GetRemoteImage(new Uri(profileImageUrl)).ConfigureAwait(false);
if (found)
{
return new Bitmap(imageFileInfo.FullName);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
return DefaultValueService.DefaultProfileImage;
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using MySocialPortalDesktop.Comparer;
using MySocialPortalDesktop.Factory;
using ReactiveUI;
namespace MySocialPortalDesktop.ViewModels
{
public class PeopleListViewModel
public class PeopleListViewModel : ViewModelBase
{
private string _filterText;
public string FilterText
{
get => _filterText;
set
{
this.RaiseAndSetIfChanged(ref _filterText, value);
UpdateViewFilter();
}
}
public ObservableCollection<PersonViewModel> People { get; }
public PeopleListViewModel()
{
var allPeople = RepositoryFactory.Instance.MainPeopleRepository.ListAll();
var peopleVms = allPeople?.Select(p => new PersonViewModel(p)) ?? new List<PersonViewModel>();
var peopleVms = allPeople?.Select(p => new PersonViewModel(p)).ToList() ?? new List<PersonViewModel>();
People = new ObservableCollection<PersonViewModel>(peopleVms);
FullPeopleList = new List<PersonViewModel>(peopleVms);
CurrentViewFilter = FilterText = "";
}
public void ChangeSortOrderCommand(string sortName)
{
switch(sortName)
{
case "Name (A-Z)":
CurrentComparer = new PersonViewModelComparer(true, PersonViewModelComparer.SortFieldEnum.DisplayName);
break;
case "Name (Z-A)":
CurrentComparer = new PersonViewModelComparer(false, PersonViewModelComparer.SortFieldEnum.DisplayName);
break;
case "Username (A-Z)":
CurrentComparer = new PersonViewModelComparer(true, PersonViewModelComparer.SortFieldEnum.DisplayUsername);
break;
case "Username (Z-A)":
CurrentComparer = new PersonViewModelComparer(false, PersonViewModelComparer.SortFieldEnum.DisplayUsername);
break;
default:
CurrentComparer = null;
break;
}
UpdateSortedView();
}
private IComparer<PersonViewModel> CurrentComparer { get; set; }
private string CurrentViewFilter { get; set; }
private List<PersonViewModel> FullPeopleList { get; }
private void UpdateSortedView()
{
if(CurrentComparer == null)
{
return;
}
var sortedFriends = new List<PersonViewModel>(People);
sortedFriends.Sort(CurrentComparer);
People.Clear();
sortedFriends.ForEach(f => People.Add(f));
}
private void UpdateViewFilter(bool forceRefresh = false)
{
if(FilterText == CurrentViewFilter && !forceRefresh)
{
return;
}
CurrentViewFilter = FilterText;
var filter = FilterText.ToUpperInvariant();
var filteredPeople = FilterText.Length == 0 ? new List<PersonViewModel>(FullPeopleList)
: FullPeopleList.FindAll(
f => f.DisplayName.ToUpperInvariant().Contains(filter, StringComparison.InvariantCulture)
|| f.DisplayName.Contains(filter, StringComparison.InvariantCulture));
if(CurrentComparer != null)
{
filteredPeople.Sort(CurrentComparer);
}
People.Clear();
filteredPeople.ForEach(f => People.Add(f));
}
}
}
\ No newline at end of file
using System.Linq;
using Avalonia.Media.Imaging;
using MySocialPortalDesktop.Services;
using MySocialPortalDesktop.Util;
using MySocialPortalLib.Model;
using ReactiveUI;
......@@ -49,9 +50,8 @@ namespace MySocialPortalDesktop.ViewModels
private void UpdatePersonData()
{
DisplayName = string.IsNullOrWhiteSpace(Person.Name) ? "" : Person.Name;
var username = Person?.SocialMediaAccounts?.Values?.First()?.ProfileId ?? "N/A";
DisplayUsername = username;
DisplayIcon = DefaultValueService.DefaultProfileImage;
DisplayUsername = PersonDataGenerator.GetDefaultUserName(Person).Result;
DisplayIcon = PersonDataGenerator.LoadProfileImage(Person).Result;
}
}
......
......@@ -9,6 +9,7 @@ using System.IO;
using System.Linq;
using LinqToTwitter.Net;
using MySocialPortalDesktop.Services;
using MySocialPortalDesktop.Util;
namespace MySocialPortalDesktop.ViewModels
{
......@@ -71,7 +72,7 @@ namespace MySocialPortalDesktop.ViewModels
if (author != null)
{
Title = author.Name;
LoadProfileImage(author);
ProfileImage = PersonDataGenerator.LoadProfileImage(author).Result;
}
OriginalSocialMediaSystem = post.OriginalSocialMediaSystem;
......@@ -103,26 +104,5 @@ namespace MySocialPortalDesktop.ViewModels
}
}
}
protected async void LoadProfileImage(Person author)
{
var profileImageUrl = author.SocialMediaAccounts.First().Value.ProfilePhotoPath;
try
{
if (!string.IsNullOrWhiteSpace(profileImageUrl))
{
var (found, imageFileInfo) = await ServiceFactory.Instance.ProfileImageService
.GetRemoteImage(new Uri(profileImageUrl)).ConfigureAwait(false);
if (found)
{
ProfileImage = new Bitmap(imageFileInfo.FullName);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
}
}
\ No newline at end of file
......@@ -27,7 +27,7 @@
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="300" Width="Auto"/>
<ColumnDefinition MinWidth="300" Width="300"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
......
......@@ -17,6 +17,16 @@
</UserControl.Styles>
<Grid RowDefinitions="Auto,*" ColumnDefinitions="*">
<Grid Grid.Row="0" Grid.Column="0" RowDefinitions="Auto" ColumnDefinitions="Auto,*" Margin="2">
<ComboBox Name="SortOrderComboBox" Grid.Row="0" Grid.Column="0" Width="100" SelectedIndex="0" >
<ComboBoxItem Content="None" />
<ComboBoxItem Content="Name (A-Z)" />
<ComboBoxItem Content="Name (Z-A)" />
<ComboBoxItem Content="Username (A-Z)" />
<ComboBoxItem Content="Username (Z-A)" />
</ComboBox>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding FilterText}" />
</Grid>
<ListBox Grid.Row="1" Grid.Column="0" Name="FriendsList" Items="{Binding People}">
<ListBox.DataTemplates>
<DataTemplate DataType="vm:PersonViewModel">
......
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using MySocialPortalDesktop.ViewModels;
namespace MySocialPortalDesktop.Views
{
......@@ -9,11 +10,28 @@ namespace MySocialPortalDesktop.Views
public PeopleListView()
{
InitializeComponent();
SetupCallbacks();
}
private void InitializeComponent()
{
AvaloniaXamlLoader.Load(this);
}
private void SetupCallbacks()
{
var sortOrder = this.Find<ComboBox>("SortOrderComboBox");
sortOrder.SelectionChanged += (sender, e) =>
{
var vm = this.DataContext as PeopleListViewModel;
if (vm == null)
{
return;
}
var selection = (e?.AddedItems[0] as ComboBoxItem)?.Content?.ToString();
vm.ChangeSortOrderCommand(selection);
};
}
}
}
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment