diff --git a/feeluown/gui/components/player_playlist.py b/feeluown/gui/components/player_playlist.py index d4f83dd9a..4619c17dc 100644 --- a/feeluown/gui/components/player_playlist.py +++ b/feeluown/gui/components/player_playlist.py @@ -102,4 +102,15 @@ def scroll_to_current_song(self): def _remove_songs(self, songs): for song in songs: - self._app.playlist.remove(song) + playlist_songs = self._app.playlist.list() + if ( + self._app.playlist.mode is PlaylistMode.fm + # playlist_songs should not be empty, just for robustness + and playlist_songs + and song == self._app.playlist.current_song + and playlist_songs[-1] == song + ): + self._app.show_msg("FM 模式下,如果当前歌曲是最后一首歌,则无法移除,请稍后再尝试移除", timeout=3000) + self._app.playlist.next() + else: + self._app.playlist.remove(song) diff --git a/feeluown/player/playlist.py b/feeluown/player/playlist.py index 9d0faf825..d4fed7c4b 100644 --- a/feeluown/player/playlist.py +++ b/feeluown/player/playlist.py @@ -315,8 +315,13 @@ def remove_no_lock(self, song): self._songs.remove(song) new_next_song = self._get_next_song_no_lock() self.set_existing_song_as_current_song(new_next_song) + elif next_song is None and self.mode is PlaylistMode.fm: + # The caller should not remove the current song when it + # is the last song in fm mode. + logger.error("Can't remove the last song in fm mode, will play next") + self._next_no_lock() + return else: - next_song = self._get_next_song_no_lock() self._songs.remove(song) self.set_existing_song_as_current_song(next_song) else: diff --git a/setup.cfg b/setup.cfg index 00bb23f1e..019fd15e7 100644 --- a/setup.cfg +++ b/setup.cfg @@ -40,6 +40,7 @@ addopts = -q --cov-report= --cov=feeluown --doctest-modules +asyncio_default_fixture_loop_scope = function [mypy-feeluown.mpv] ignore_errors = True diff --git a/tests/player/test_playlist.py b/tests/player/test_playlist.py index 00efe8a91..410d8f7aa 100644 --- a/tests/player/test_playlist.py +++ b/tests/player/test_playlist.py @@ -296,8 +296,13 @@ def feed_playlist(): @pytest.mark.asyncio -async def test_playlist_remove_current_song(app_mock): - pass +async def test_playlist_remove_current_song(pl, song1, mocker): + # Remove the current song, and it is the last song in the playlist. + mock_emit = mocker.patch.object(pl.eof_reached, 'emit') + pl.mode = PlaylistMode.fm + pl._current_song = song1 + pl.remove(song1) + assert mock_emit.called @pytest.mark.asyncio