diff --git a/feeluown/gui/pages/model.py b/feeluown/gui/pages/model.py index 38a021b384..dfe37a1996 100644 --- a/feeluown/gui/pages/model.py +++ b/feeluown/gui/pages/model.py @@ -1,5 +1,7 @@ from feeluown.library import V2SupportedModelTypes, AlbumModel, NotSupported +from feeluown.library.provider_protocol import SupportsPlaylistRemoveSong from feeluown.utils import aio +from feeluown.utils.aio import run_fn, run_afn from feeluown.utils.reader import create_reader from feeluown.library import ModelType, reverse @@ -170,7 +172,9 @@ async def render(self): self.show_cover(playlist.cover, reverse(playlist) + '/cover')) - self.songs_table.remove_song_func = self.remove_song + provider = self._app.library.get(self.playlist.source) + if isinstance(provider, SupportsPlaylistRemoveSong): + self.songs_table.remove_song_func = self.remove_song async def _show_songs(self): reader = await aio.run_fn(self._app.library.playlist_create_songs_rd, @@ -178,9 +182,14 @@ async def _show_songs(self): self.show_songs(reader=reader, show_count=True) def remove_song(self, song): - # FIXME: this may block the whole app. - if self._app.library.playlist_remove_song(self.playlist, song) is True: - # Re-render songs table so that user can see that the song is removed. - aio.run_afn(self._show_songs) - else: - self._app.show_msg('移除歌曲失败') + + async def do(): + provider = self._app.library.get(self.playlist.source) + if await run_fn(provider.playlist_remove_song, self.playlist, song) is True: + # Re-render songs table so that user can see that the song is removed. + aio.run_afn(self._show_songs) + self._app.show_msg(f'移除歌曲 {song} 成功') + else: + self._app.show_msg(f'移除歌曲 {song} 失败') + + run_afn(do) diff --git a/feeluown/gui/widgets/playlists.py b/feeluown/gui/widgets/playlists.py index b13c24e05e..30675832c6 100644 --- a/feeluown/gui/widgets/playlists.py +++ b/feeluown/gui/widgets/playlists.py @@ -9,6 +9,8 @@ QAbstractItemView, QMenu ) +from feeluown.library import SupportsPlaylistAddSong +from feeluown.utils.aio import run_afn, run_fn from .textlist import TextlistModel, TextlistView @@ -124,16 +126,23 @@ def dropEvent(self, e): playlist = index.data(Qt.UserRole) self._results[index.row] = (index, None) self.viewport().update() - try: - # FIXME: this may block the app. - app = self.parent().parent()._app # type: ignore[attr-defined] - is_success = app.library.playlist_add_song(playlist, song) - except: # noqa, to avoid crash. - logger.exception('add song to playlist failed') + + async def do(): is_success = False - self._results[index.row] = (index, is_success) - self.viewport().update() - self._result_timer.start(2000) + app = self.parent().parent()._app # type: ignore[attr-defined] + try: + provider = app.library.get(playlist.source) + if isinstance(provider, SupportsPlaylistAddSong): + is_success = await run_fn(provider.playlist_add_song, playlist, song) + except: # noqa, to avoid crash. + logger.exception('add song to playlist failed') + is_success = False + app.show_msg(f"添加歌曲 {song} 到播放列表 {'成功' if is_success is True else '失败'}") + self._results[index.row] = (index, is_success) + self.viewport().update() + self._result_timer.start(2000) + + run_afn(do) e.accept() def dragMoveEvent(self, e): diff --git a/feeluown/gui/widgets/songs.py b/feeluown/gui/widgets/songs.py index f3e8a5dbee..d471997d34 100644 --- a/feeluown/gui/widgets/songs.py +++ b/feeluown/gui/widgets/songs.py @@ -642,12 +642,13 @@ def contextMenuEvent(self, event): menu.addAction(add_to_playlist_action) # remove song action - if self.remove_song_func is not None: - remove_song_action = QAction('移除歌曲', menu) - remove_song_action.triggered.connect( - lambda: self._remove_by_indexes(indexes)) - menu.addSeparator() - menu.addAction(remove_song_action) + remove_song_action = QAction('移除歌曲', menu) + remove_song_action.triggered.connect( + lambda: self._remove_by_indexes(indexes)) + menu.addSeparator() + menu.addAction(remove_song_action) + if self.remove_song_func is None: + remove_song_action.setDisabled(True) model = self.model() models = [model.data(index, Qt.UserRole) for index in indexes] diff --git a/feeluown/library/library.py b/feeluown/library/library.py index c10b65f100..ff942104f5 100644 --- a/feeluown/library/library.py +++ b/feeluown/library/library.py @@ -29,7 +29,7 @@ check_flag as check_flag_impl, SupportsCurrentUser, SupportsAlbumSongsReader, SupportsSongLyric, SupportsSongMV, SupportsSongMultiQuality, - SupportsPlaylistRemoveSong, SupportsPlaylistAddSong, SupportsPlaylistSongsReader, + SupportsPlaylistSongsReader, SupportsArtistSongsReader, SupportsArtistAlbumsReader, SupportsVideoMultiQuality, SupportsArtistContributedAlbumsReader, ) @@ -502,26 +502,6 @@ def playlist_create_songs_rd(self, playlist): playlist, ) - def playlist_remove_song(self, playlist, song) -> bool: - """Remove a song from the playlist - - :return: true if the song is not in playlist anymore. - """ - provider = self.get_or_raise(playlist.source) - if isinstance(provider, SupportsPlaylistRemoveSong): - return provider.playlist_remove_song(playlist, song) - raise NotSupported - - def playlist_add_song(self, playlist, song) -> bool: - """Add a song to the playlist - - :return: true if the song exists in playlist. - """ - provider = self.get_or_raise(playlist.source) - if isinstance(provider, SupportsPlaylistAddSong): - return provider.playlist_add_song(playlist, song) - raise NotSupported - # ------------------------- # generic methods for model # ------------------------- diff --git a/feeluown/library/models.py b/feeluown/library/models.py index fc9aa73f4d..c3a16bb354 100644 --- a/feeluown/library/models.py +++ b/feeluown/library/models.py @@ -230,7 +230,7 @@ class BriefSongModel(BaseBriefModel): duration_ms: str = '' def __str__(self): - return f'{self.title} - {self.artists_name}' + return f'[{self.source}]{self.title}•{self.artists_name}' class BriefVideoModel(BaseBriefModel): @@ -289,6 +289,9 @@ class SongModel(BaseNormalModel): # to fetch a image url of the song. pic_url: str = '' + def __str__(self): + return f'[{self.source}]{self.title}•{self.artists_name}' + @property def artists_name(self): return fmt_artists(self.artists)