Implemented SourceList to observe changes to reflect in UI

This commit is contained in:
Enrico Ludwig 2024-09-07 16:30:12 +02:00
parent 8fec3171df
commit f781fe0ff9
4 changed files with 54 additions and 60 deletions

View File

@ -3,7 +3,7 @@ using System.IO;
namespace BetterRaid.Misc; namespace BetterRaid.Misc;
public class Constants public static class Constants
{ {
// General // General
public const string ChannelPlaceholderImageUrl = "https://cdn.pixabay.com/photo/2018/11/13/22/01/avatar-3814081_1280.png"; public const string ChannelPlaceholderImageUrl = "https://cdn.pixabay.com/photo/2018/11/13/22/01/avatar-3814081_1280.png";
@ -17,7 +17,7 @@ public class Constants
_ => throw new PlatformNotSupportedException($"Your platform '{Environment.OSVersion.Platform}' is not supported. Please report this issue here: https://www.github.com/zion-networks/BetterRaid/issues") _ => throw new PlatformNotSupportedException($"Your platform '{Environment.OSVersion.Platform}' is not supported. Please report this issue here: https://www.github.com/zion-networks/BetterRaid/issues")
}; };
public static string TwitchOAuthAccessTokenFilePath => Path.Combine(BetterRaidDataPath, ".access_token"); public static string TwitchOAuthAccessTokenFilePath => Path.Combine(BetterRaidDataPath, ".access_token");
public static string DatabaseFilePath => Path.Combine(BetterRaidDataPath, "db.json"); public static string DatabaseFilePath => Path.Combine(BetterRaidDataPath, "brdb.json");
// Twitch API // Twitch API
public const string TwitchClientId = "kkxu4jorjrrc5jch1ito5i61hbev2o"; public const string TwitchClientId = "kkxu4jorjrrc5jch1ito5i61hbev2o";

View File

@ -12,10 +12,10 @@ namespace BetterRaid.Models;
public class TwitchChannel : INotifyPropertyChanged public class TwitchChannel : INotifyPropertyChanged
{ {
private string? _id; private string? _id;
private string _name;
private string? _broadcasterId; private string? _broadcasterId;
private string? _viewerCount; private string? _viewerCount;
private bool _isLive; private bool _isLive;
private string? _name;
private string? _displayName; private string? _displayName;
private string? _thumbnailUrl; private string? _thumbnailUrl;
private string? _category; private string? _category;
@ -48,7 +48,7 @@ public class TwitchChannel : INotifyPropertyChanged
} }
} }
public string? Name public string Name
{ {
get => _name; get => _name;
set set
@ -156,9 +156,9 @@ public class TwitchChannel : INotifyPropertyChanged
} }
} }
public TwitchChannel(string channelName) public TwitchChannel(string? channelName)
{ {
Name = channelName; _name = channelName ?? string.Empty;
} }
public void UpdateChannelData(ITwitchService service) public void UpdateChannelData(ITwitchService service)

View File

@ -1,6 +1,6 @@
using System; using System;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Reactive.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
@ -8,6 +8,8 @@ using BetterRaid.Extensions;
using BetterRaid.Models; using BetterRaid.Models;
using BetterRaid.Services; using BetterRaid.Services;
using BetterRaid.Views; using BetterRaid.Views;
using DynamicData;
using DynamicData.Binding;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using ReactiveUI; using ReactiveUI;
@ -15,43 +17,55 @@ namespace BetterRaid.ViewModels;
public class MainWindowViewModel : ViewModelBase public class MainWindowViewModel : ViewModelBase
{ {
private ObservableCollection<TwitchChannel> _channels = []; private readonly SourceList<TwitchChannel> _sourceList;
private readonly ISynchronizaionService _synchronizationService; private readonly ISynchronizaionService _synchronizationService;
private readonly ILogger<MainWindowViewModel> _logger; private readonly ILogger<MainWindowViewModel> _logger;
private readonly IWebToolsService _webTools; private readonly IWebToolsService _webTools;
private readonly IDatabaseService _db; private readonly IDatabaseService _db;
private readonly ITwitchService _twitch; private readonly ITwitchService _twitch;
private string? _filter; private string _filter;
private bool _onlyOnline; private bool _onlyOnline;
private readonly ReadOnlyObservableCollection<TwitchChannel> _filteredChannels;
public ITwitchService Twitch => _twitch; public ITwitchService Twitch => _twitch;
public ObservableCollection<TwitchChannel> Channels public ReadOnlyObservableCollection<TwitchChannel> FilteredChannels => _filteredChannels;
{
get => _channels;
set => this.RaiseAndSetIfChanged(ref _channels, value);
}
public ObservableCollection<TwitchChannel> FilteredChannels => GetFilteredChannels(); public string Filter
public string? Filter
{ {
get => _filter; get => _filter;
set set
{ {
this.RaiseAndSetIfChanged(ref _filter, value); this.RaiseAndSetIfChanged(ref _filter, value);
LoadChannelsFromDb();
_sourceList.Edit(innerList =>
{
if (_db.Database == null)
return;
innerList.Clear();
innerList.AddRange(_db.Database.Channels);
});
} }
} }
public bool OnlyOnline public bool OnlyOnline
{ {
get => _db.OnlyOnline; get => _onlyOnline;
set set
{ {
this.RaiseAndSetIfChanged(ref _onlyOnline, value); this.RaiseAndSetIfChanged(ref _onlyOnline, value);
LoadChannelsFromDb();
_sourceList.Edit(innerList =>
{
if (_db.Database == null)
return;
innerList.Clear();
innerList.AddRange(_db.Database.Channels);
});
} }
} }
@ -69,9 +83,18 @@ public class MainWindowViewModel : ViewModelBase
_webTools = webTools; _webTools = webTools;
_db = db; _db = db;
_synchronizationService = synchronizationService; _synchronizationService = synchronizationService;
_filter = string.Empty;
_twitch.UserLoginChanged += OnUserLoginChanged; _twitch.UserLoginChanged += OnUserLoginChanged;
_twitch.TwitchChannelUpdated += OnTwitchChannelUpdated;
_sourceList = new SourceList<TwitchChannel>();
_sourceList.Connect()
.Filter(channel => channel.Name.Contains(_filter, StringComparison.OrdinalIgnoreCase))
.Filter(channel => !OnlyOnline || channel.IsLive)
.Sort(SortExpressionComparer<TwitchChannel>.Descending(channel => channel.IsLive))
.ObserveOn(RxApp.MainThreadScheduler)
.Bind(out _filteredChannels)
.Subscribe();
LoadChannelsFromDb(); LoadChannelsFromDb();
} }
@ -107,49 +130,20 @@ public class MainWindowViewModel : ViewModelBase
return; return;
} }
foreach (var channel in Channels) foreach (var channel in _db.Database.Channels)
{
_twitch.UnregisterFromEvents(channel);
}
Channels.Clear();
var channels = _db.Database.Channels
//.ToList()
//.OrderByDescending(c => c.IsLive)
//.Where(c => OnlyOnline && c.IsLive || !OnlyOnline)
//.Where(c => string.IsNullOrWhiteSpace(Filter) || c.Name?.Contains(Filter, StringComparison.CurrentCultureIgnoreCase) == true)
.ToList();
foreach (var channel in channels)
{ {
Task.Run(() => Task.Run(() =>
{ {
channel.UpdateChannelData(_twitch); channel.UpdateChannelData(_twitch);
_twitch.RegisterForEvents(channel); _twitch.RegisterForEvents(channel);
}); });
Channels.Add(channel);
}
} }
private void OnTwitchChannelUpdated(object? sender, TwitchChannel channel) _sourceList.Edit(innerList => innerList.AddRange(_db.Database.Channels));
{
LoadChannelsFromDb();
} }
private void OnUserLoginChanged(object? sender, EventArgs e) private void OnUserLoginChanged(object? sender, EventArgs e)
{ {
this.RaisePropertyChanged(nameof(IsLoggedIn)); this.RaisePropertyChanged(nameof(IsLoggedIn));
} }
private ObservableCollection<TwitchChannel> GetFilteredChannels()
{
var filteredChannels = Channels
.Where(channel => OnlyOnline == false || channel.IsLive)
.Where(channel => string.IsNullOrWhiteSpace(Filter) || channel.Name?.Contains(Filter, StringComparison.OrdinalIgnoreCase) == true)
.ToList();
return new ObservableCollection<TwitchChannel>(filteredChannels);
}
} }

View File

@ -115,7 +115,7 @@
IsScrollInertiaEnabled="True" /> IsScrollInertiaEnabled="True" />
</ScrollViewer.GestureRecognizers> </ScrollViewer.GestureRecognizers>
<!--<ListBox Items="{Binding FilteredChannels, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" <ListBox ItemsSource="{Binding FilteredChannels, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
SelectionMode="Single" SelectionMode="Single"
SelectionChanged="SelectingItemsControl_OnSelectionChanged"> SelectionChanged="SelectingItemsControl_OnSelectionChanged">
@ -240,7 +240,7 @@
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ListBox.ItemTemplate> </ListBox.ItemTemplate>
</ListBox>--> </ListBox>
</ScrollViewer> </ScrollViewer>