From 9331604de4b7739773c453e57f5223695710a326 Mon Sep 17 00:00:00 2001 From: Divyansh Bhatia Date: Wed, 15 Oct 2025 22:11:37 +0530 Subject: [PATCH] Feature: Enqueue in recent played #690 --- .../ViewModels/HomePageViewModel.cs | 14 +++++++-- .../ViewModels/MediaListViewModel.cs | 31 +++++++++++++------ 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Screenbox.Core/ViewModels/HomePageViewModel.cs b/Screenbox.Core/ViewModels/HomePageViewModel.cs index 7ae150568..983eb1c6b 100644 --- a/Screenbox.Core/ViewModels/HomePageViewModel.cs +++ b/Screenbox.Core/ViewModels/HomePageViewModel.cs @@ -177,7 +177,7 @@ private void MoveOrInsert(StorageFile file, string token, int desiredIndex) } [RelayCommand] - private void Play(MediaViewModel media) + private async Task Play(MediaViewModel media) { if (media.IsMediaActive) { @@ -185,7 +185,17 @@ private void Play(MediaViewModel media) } else { - Messenger.Send(new PlayMediaMessage(media, false)); + // If the recent item is a StorageFile, use PlayFilesMessage so the playlist can be + // populated with neighboring files (based on settings) and Next/Previous can work. + if (media.Source is StorageFile file) + { + var query = await _filesService.GetNeighboringFilesQueryAsync(file); + Messenger.Send(new PlayFilesMessage(new IStorageItem[] { file }, query)); + } + else + { + Messenger.Send(new PlayMediaMessage(media, false)); + } } } diff --git a/Screenbox.Core/ViewModels/MediaListViewModel.cs b/Screenbox.Core/ViewModels/MediaListViewModel.cs index bbc988dc1..489b5cc24 100644 --- a/Screenbox.Core/ViewModels/MediaListViewModel.cs +++ b/Screenbox.Core/ViewModels/MediaListViewModel.cs @@ -181,19 +181,29 @@ private void OnPlaybackStateChanged(IMediaPlayer sender, object args) public async void Receive(PlayFilesMessage message) { IReadOnlyList files = message.Value; - _neighboringFilesQuery = message.NeighboringFilesQuery; + _neighboringFilesQuery = message.NeighboringFilesQuery ?? _neighboringFilesQuery; if (files.Count == 1 && files[0] is StorageFile file) { var media = _mediaFactory.GetSingleton(file); - // The current play queue may already have the file already. Just play the file in this case. + // If the file already exists in the queue, just play it, but ensure neighboring query is ready if (Items.Contains(media)) { + if (_neighboringFilesQuery == null) + { + _neighboringFilesQuery = await _filesService.GetNeighboringFilesQueryAsync(file); + } + PlaySingle(media); return; } - // If there is only 1 file, play it immediately - // Avoid waiting to get all the neighboring files then play, which may cause delay + // Prepare neighboring files query before starting playback so Next is enabled immediately + if (_neighboringFilesQuery == null) + { + _neighboringFilesQuery = await _filesService.GetNeighboringFilesQueryAsync(file); + } + + // If there is only 1 file, play it immediately to avoid delay ClearPlaylist(); if (_mediaPlayer == null) { @@ -207,8 +217,7 @@ public async void Receive(PlayFilesMessage message) // If there are more than one item in the queue, file is already a playlist, no need to check for neighboring files if (Items.Count > 1) return; - _neighboringFilesQuery ??= await _filesService.GetNeighboringFilesQueryAsync(file); - // Populate the play queue with neighboring media if needed + // Populate the play queue with neighboring media if needed (non-blocking for initial play) if (!_settingsService.EnqueueAllFilesInFolder || _neighboringFilesQuery == null) return; _playFilesCts?.Cancel(); using CancellationTokenSource cts = new(); @@ -809,14 +818,16 @@ private void OnEndReached(IMediaPlayer sender, object? args) { switch (RepeatMode) { - case MediaPlaybackAutoRepeatMode.List when CurrentIndex == Items.Count - 1: - PlaySingle(Items[0]); - break; case MediaPlaybackAutoRepeatMode.Track: sender.Position = TimeSpan.Zero; break; + case MediaPlaybackAutoRepeatMode.List when CurrentIndex == Items.Count - 1 && Items.Count > 0: + PlaySingle(Items[0]); + break; default: - if (Items.Count > 1) _ = NextAsync(); + // Always attempt next. If only one item and a neighboring files query is available, + // NextAsync will move to the next file in the same folder. + _ = NextAsync(); break; } });