diff --git a/TV Player WPF/ProgramsList.xaml b/TV Player WPF/ProgramsList.xaml index b3773a7..1816e91 100644 --- a/TV Player WPF/ProgramsList.xaml +++ b/TV Player WPF/ProgramsList.xaml @@ -10,6 +10,9 @@ SelectionMode="Single" Style="{StaticResource ListBoxView}" SelectedItem="{Binding SelectedItem}" BorderThickness="0" SnapsToDevicePixels="True" + VirtualizingStackPanel.IsVirtualizing="True" + VirtualizingStackPanel.VirtualizationMode="Recycling" + VirtualizingStackPanel.CacheLength="5" PreviewMouseDown="ListView_PreviewMouseDown" PreviewMouseUp="ListView_PreviewMouseUp" PreviewMouseMove="ListView_MouseMove" diff --git a/TV Player WPF/TV Player WPF.csproj b/TV Player WPF/TV Player WPF.csproj index ca7df6a..58aeb7d 100644 --- a/TV Player WPF/TV Player WPF.csproj +++ b/TV Player WPF/TV Player WPF.csproj @@ -20,13 +20,13 @@ - - + + true - + - + diff --git a/TV Player WPF/ViewModels/ProgramsListViewModel.cs b/TV Player WPF/ViewModels/ProgramsListViewModel.cs index 6dd94e6..62a7c69 100644 --- a/TV Player WPF/ViewModels/ProgramsListViewModel.cs +++ b/TV Player WPF/ViewModels/ProgramsListViewModel.cs @@ -1,13 +1,18 @@ using CommunityToolkit.Mvvm.Input; +using System.Collections.ObjectModel; +using System.Reactive.Linq; +using System.Reactive; using System.Windows.Input; using TV_Player.ViewModels; +using System.Windows; +using System.Reactive.Concurrency; namespace TV_Player { public class ProgramsListViewModel : ObservableViewModelBase, IDisposable { - private List _programs; - public List Programs + private ObservableCollection _programs = new ObservableCollection(); + public ObservableCollection Programs { get => _programs; set => SetProperty(ref _programs, value); @@ -15,13 +20,17 @@ namespace TV_Player public M3UInfo SelectedItem { get; set; } public ICommand ItemSelectedCommand { get; } - private IDisposable _programSubscriber; + private CancellationTokenSource cts = new CancellationTokenSource(); - public ProgramsListViewModel(string playlistName,GroupInfo groupInfo) + + public ProgramsListViewModel(string playlistName, GroupInfo groupInfo) { TVPlayerViewModel.Instance.TopPanelVisible(true, groupInfo.Name); ItemSelectedCommand = new RelayCommand(OnItemSelected); - _programSubscriber = TVPlayerViewModel.Instance.CurrentProgrmsData.AllPrograms.Subscribe(x => Programs = x.Where(p => p.GroupTitle == groupInfo.Name).ToList()); + //_programSubscriber = TVPlayerViewModel.Instance.CurrentProgrmsData.AllPrograms.Subscribe(x => Programs = x.Where(p => p.GroupTitle == groupInfo.Name)); + + SubscribeToProgramsData(groupInfo); + TVPlayerViewModel.Instance.SetBackButtonAction(new Action(() => { @@ -29,6 +38,36 @@ namespace TV_Player })); } + private void SubscribeToProgramsData(GroupInfo groupInfo) + { + TVPlayerViewModel.Instance.CurrentProgrmsData.AllPrograms.ObserveOn(Scheduler.Default) + .Subscribe(newPrograms => + { + var filteredPrograms = newPrograms.Where(p => p.GroupTitle == groupInfo.Name).ToList(); + + Programs.Clear(); + const int batchSize = 100; // Define the batch size + int totalItems = filteredPrograms.Count; + + for (int i = 0; i < totalItems; i += batchSize) + { + // Take the next batch of 100 items + var batch = filteredPrograms.Skip(i).Take(batchSize).ToList(); + Application.Current.Dispatcher.Invoke(() => + { + // Add the batch to the collection + foreach (var program in batch) + { + + Programs.Add(program); + + } + }); + Task.Delay(500, cts.Token).Wait(); + } + }, cts.Token); + } + private void OnItemSelected() { TVPlayerViewModel.Instance.ShowPlayerScreen(SelectedItem); @@ -36,7 +75,7 @@ namespace TV_Player public void Dispose() { - _programSubscriber.Dispose(); + cts.Cancel(); } } }