diff --git a/Misc/Constants.cs b/Misc/Constants.cs index 87b0952..d32ec88 100644 --- a/Misc/Constants.cs +++ b/Misc/Constants.cs @@ -3,7 +3,7 @@ using System.IO; namespace BetterRaid.Misc; -public class Constants +public static class Constants { // General 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") }; 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 public const string TwitchClientId = "kkxu4jorjrrc5jch1ito5i61hbev2o"; diff --git a/Models/TwitchChannel.cs b/Models/TwitchChannel.cs index 0b839a7..21ddcb7 100644 --- a/Models/TwitchChannel.cs +++ b/Models/TwitchChannel.cs @@ -12,10 +12,10 @@ namespace BetterRaid.Models; public class TwitchChannel : INotifyPropertyChanged { private string? _id; + private string _name; private string? _broadcasterId; private string? _viewerCount; private bool _isLive; - private string? _name; private string? _displayName; private string? _thumbnailUrl; private string? _category; @@ -48,7 +48,7 @@ public class TwitchChannel : INotifyPropertyChanged } } - public string? Name + public string Name { get => _name; 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) diff --git a/ViewModels/MainWindowViewModel.cs b/ViewModels/MainWindowViewModel.cs index 854c628..90365a7 100644 --- a/ViewModels/MainWindowViewModel.cs +++ b/ViewModels/MainWindowViewModel.cs @@ -1,6 +1,6 @@ using System; using System.Collections.ObjectModel; -using System.Linq; +using System.Reactive.Linq; using System.Threading; using System.Threading.Tasks; using Avalonia.Controls; @@ -8,6 +8,8 @@ using BetterRaid.Extensions; using BetterRaid.Models; using BetterRaid.Services; using BetterRaid.Views; +using DynamicData; +using DynamicData.Binding; using Microsoft.Extensions.Logging; using ReactiveUI; @@ -15,43 +17,55 @@ namespace BetterRaid.ViewModels; public class MainWindowViewModel : ViewModelBase { - private ObservableCollection _channels = []; + private readonly SourceList _sourceList; + private readonly ISynchronizaionService _synchronizationService; private readonly ILogger _logger; private readonly IWebToolsService _webTools; private readonly IDatabaseService _db; private readonly ITwitchService _twitch; - - private string? _filter; + + private string _filter; private bool _onlyOnline; - + private readonly ReadOnlyObservableCollection _filteredChannels; + public ITwitchService Twitch => _twitch; - public ObservableCollection Channels - { - get => _channels; - set => this.RaiseAndSetIfChanged(ref _channels, value); - } - - public ObservableCollection FilteredChannels => GetFilteredChannels(); + public ReadOnlyObservableCollection FilteredChannels => _filteredChannels; - public string? Filter + public string Filter { get => _filter; set { this.RaiseAndSetIfChanged(ref _filter, value); - LoadChannelsFromDb(); + + _sourceList.Edit(innerList => + { + if (_db.Database == null) + return; + + innerList.Clear(); + innerList.AddRange(_db.Database.Channels); + }); } } public bool OnlyOnline { - get => _db.OnlyOnline; + get => _onlyOnline; set { this.RaiseAndSetIfChanged(ref _onlyOnline, value); - LoadChannelsFromDb(); + + _sourceList.Edit(innerList => + { + if (_db.Database == null) + return; + + innerList.Clear(); + innerList.AddRange(_db.Database.Channels); + }); } } @@ -69,10 +83,19 @@ public class MainWindowViewModel : ViewModelBase _webTools = webTools; _db = db; _synchronizationService = synchronizationService; - + _filter = string.Empty; + _twitch.UserLoginChanged += OnUserLoginChanged; - _twitch.TwitchChannelUpdated += OnTwitchChannelUpdated; - + + _sourceList = new SourceList(); + _sourceList.Connect() + .Filter(channel => channel.Name.Contains(_filter, StringComparison.OrdinalIgnoreCase)) + .Filter(channel => !OnlyOnline || channel.IsLive) + .Sort(SortExpressionComparer.Descending(channel => channel.IsLive)) + .ObserveOn(RxApp.MainThreadScheduler) + .Bind(out _filteredChannels) + .Subscribe(); + LoadChannelsFromDb(); } @@ -106,50 +129,21 @@ public class MainWindowViewModel : ViewModelBase _logger.LogError("Database is null"); return; } - - foreach (var channel in 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) + foreach (var channel in _db.Database.Channels) { Task.Run(() => { channel.UpdateChannelData(_twitch); _twitch.RegisterForEvents(channel); }); - - Channels.Add(channel); } - } - - private void OnTwitchChannelUpdated(object? sender, TwitchChannel channel) - { - LoadChannelsFromDb(); + + _sourceList.Edit(innerList => innerList.AddRange(_db.Database.Channels)); } private void OnUserLoginChanged(object? sender, EventArgs e) { this.RaisePropertyChanged(nameof(IsLoggedIn)); } - - private ObservableCollection 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(filteredChannels); - } -} +} \ No newline at end of file diff --git a/Views/MainWindow.axaml b/Views/MainWindow.axaml index 50e1050..e333cb4 100644 --- a/Views/MainWindow.axaml +++ b/Views/MainWindow.axaml @@ -115,7 +115,7 @@ IsScrollInertiaEnabled="True" /> - +