diff --git a/src/datastores/handlers/base.js b/src/datastores/handlers/base.js index 070ebda8e8e2a..bd9f143547e28 100644 --- a/src/datastores/handlers/base.js +++ b/src/datastores/handlers/base.js @@ -147,7 +147,7 @@ class Playlists { static deleteVideoIdsByPlaylistId(_id, videoIds) { return db.playlists.updateAsync( { _id }, - { $pull: { videos: { $in: videoIds } } }, + { $pull: { videos: { videoId: { $in: videoIds } } } }, { upsert: true } ) } diff --git a/src/renderer/components/ft-list-video/ft-list-video.js b/src/renderer/components/ft-list-video/ft-list-video.js index fd58c6f67bfb9..cd1cd5880e1dd 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.js +++ b/src/renderer/components/ft-list-video/ft-list-video.js @@ -144,6 +144,24 @@ export default defineComponent({ return this.$route.name === 'history' }, + favoritesPlaylist: function () { + return this.$store.getters.getFavorites + }, + + inFavoritesPlaylist: function () { + return this.favoritesPlaylist.videos.some((video) => + video.videoId === this.id + ) + }, + + favoriteIconTheme: function () { + return this.inFavoritesPlaylist ? 'base favorite' : 'base' + }, + + favoritesText: function () { + return this.inFavoritesPlaylist ? this.$t('User Playlists.Unsave from Favorites') : this.$t('User Playlists.Save to Favorites') + }, + inUserPlaylist: function () { return this.playlistTypeFinal === 'user' || this.selectedUserPlaylist != null }, @@ -729,8 +747,59 @@ export default defineComponent({ showToast(this.$t('Channel Unhidden', { channel: channelName })) }, + toggleSaveToFavorites: function () { + if (this.inFavoritesPlaylist) { + this.removeFromFavorites() + } else { + this.addToFavorites() + } + }, + + addToFavorites: function () { + const videoData = { + videoId: this.id, + title: this.title, + author: this.channelName, + authorId: this.channelId, + description: this.description, + viewCount: this.viewCount, + lengthSeconds: this.data.lengthSeconds, + } + + const payload = { + _id: 'favorites', + videoData: videoData + } + + this.addVideo(payload) + // Update playlist's `lastUpdatedAt` + this.updatePlaylist({ _id: 'favorites' }) + + showToast(this.$t('Video.Video has been saved')) + }, + + removeFromFavorites: function () { + const payload = { + _id: 'favorites', + videoIds: [this.id] + } + + try { + this.removeVideos(payload) + // Update playlist's `lastUpdatedAt` + this.updatePlaylist({ _id: 'favorites' }) + showToast(this.$t('Video.Video has been removed from your saved list')) + } catch (e) { + showToast(this.$t('User Playlists.SinglePlaylistView.Toast.There was a problem with removing this video')) + console.error(e) + } + }, + ...mapActions([ 'openInExternalPlayer', + 'addVideo', + 'removeVideos', + 'updatePlaylist', 'updateHistory', 'removeFromHistory', 'updateChannelsHidden', diff --git a/src/renderer/components/ft-list-video/ft-list-video.vue b/src/renderer/components/ft-list-video/ft-list-video.vue index 495b3464bffcf..685380e4fac4e 100644 --- a/src/renderer/components/ft-list-video/ft-list-video.vue +++ b/src/renderer/components/ft-list-video/ft-list-video.vue @@ -43,14 +43,32 @@ :size="appearance === `watchPlaylistItem` ? 12 : 16" @click="handleExternalPlayer" /> - + + + video.videoId === this.id + ) + }, + + favoriteIconTheme: function () { + return this.inFavoritesPlaylist ? 'base favorite' : 'base' + }, + + favoritesText: function () { + return this.inFavoritesPlaylist ? this.$t('User Playlists.Unsave from Favorites') : this.$t('User Playlists.Save to Favorites') + }, + + inUserPlaylist: function () { + return this.playlistTypeFinal === 'user' || this.selectedUserPlaylist != null + }, + showPlaylists: function () { return !this.$store.getters.getHidePlaylists }, @@ -311,7 +333,58 @@ export default defineComponent({ this.showAddToPlaylistPromptForManyVideos({ videos: [videoData] }) }, + toggleSaveToFavorites: function () { + if (this.inFavoritesPlaylist) { + this.removeFromFavorites() + } else { + this.addToFavorites() + } + }, + + addToFavorites: function () { + const videoData = { + videoId: this.id, + title: this.title, + author: this.channelName, + authorId: this.channelId, + description: this.description, + viewCount: this.viewCount, + lengthSeconds: this.lengthSeconds, + } + + const payload = { + _id: 'favorites', + videoData: videoData + } + + this.addVideo(payload) + // Update playlist's `lastUpdatedAt` + this.updatePlaylist({ _id: 'favorites' }) + + showToast(this.$t('Video.Video has been saved')) + }, + + removeFromFavorites: function () { + const payload = { + _id: 'favorites', + videoIds: [this.id] + } + + try { + this.removeVideos(payload) + // Update playlist's `lastUpdatedAt` + this.updatePlaylist({ _id: 'favorites' }) + showToast(this.$t('Video.Video has been removed from your saved list')) + } catch (e) { + showToast(this.$t('User Playlists.SinglePlaylistView.Toast.There was a problem with removing this video')) + console.error(e) + } + }, + ...mapActions([ + 'addVideo', + 'removeVideos', + 'updatePlaylist', 'openInExternalPlayer', 'downloadMedia', 'showAddToPlaylistPromptForManyVideos', diff --git a/src/renderer/components/watch-video-info/watch-video-info.vue b/src/renderer/components/watch-video-info/watch-video-info.vue index af56b5c905a90..9bf99231aea21 100644 --- a/src/renderer/components/watch-video-info/watch-video-info.vue +++ b/src/renderer/components/watch-video-info/watch-video-info.vue @@ -81,6 +81,14 @@ -->
+ state.playlistsReady, getAllPlaylists: () => state.playlists, + getFavorites: () => state.playlists.find(playlist => playlist._id === 'favorites'), getPlaylist: (state) => (playlistId) => { return state.playlists.find(playlist => playlist._id === playlistId) }, @@ -253,9 +247,6 @@ const actions = { const favoritesPlaylist = payload.find((playlist) => { return playlist.playlistName === 'Favorites' || playlist._id === 'favorites' }) - const watchLaterPlaylist = payload.find((playlist) => { - return playlist.playlistName === 'Watch Later' || playlist._id === 'watchLater' - }) const defaultFavoritesPlaylist = state.defaultPlaylists.find((e) => e._id === 'favorites') if (favoritesPlaylist != null) { @@ -277,26 +268,6 @@ const actions = { } } - const defaultWatchLaterPlaylist = state.defaultPlaylists.find((e) => e._id === 'watchLater') - if (watchLaterPlaylist != null) { - // Update existing matching playlist only if it exists - if (watchLaterPlaylist._id !== defaultWatchLaterPlaylist._id || watchLaterPlaylist.protected !== defaultWatchLaterPlaylist.protected) { - const oldId = watchLaterPlaylist._id - watchLaterPlaylist._id = defaultWatchLaterPlaylist._id - watchLaterPlaylist.protected = defaultWatchLaterPlaylist.protected - if (oldId === defaultWatchLaterPlaylist._id) { - // Update playlist if ID already the same - DBPlaylistHandlers.upsert(watchLaterPlaylist) - } else { - dispatch('removePlaylist', oldId) - // DO NOT use dispatch('addPlaylist', ...) - // Which causes duplicate displayed playlist in window (But DB is fine) - // Due to the object is already in `payload` - DBPlaylistHandlers.create(watchLaterPlaylist) - } - } - } - commit('setAllPlaylists', payload) } commit('setPlaylistsReady', true) @@ -417,9 +388,9 @@ const mutations = { }, removeVideos(state, payload) { - const playlist = state.playlists.find(playlist => playlist._id === payload.playlistId) + const playlist = state.playlists.find(playlist => playlist._id === payload._id) if (playlist) { - playlist.videos = playlist.videos.filter(video => payload.videoId.indexOf(video) === -1) + playlist.videos = playlist.videos.filter(video => !payload.videoIds.includes(video.videoId)) } }, diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index c26943a73c73c..0b8ab72104abd 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -147,6 +147,8 @@ User Playlists: Create New Playlist: Create New Playlist Add to Playlist: Add to Playlist + Save to Favorites: Save to Favorites + Unsave from Favorites: Unsave from Favorites Move Video Up: Move Video Up Move Video Down: Move Video Down Remove from Playlist: Remove from Playlist @@ -707,7 +709,6 @@ Video: Remove From History: Remove From History Video has been marked as watched: Video has been marked as watched Video has been removed from your history: Video has been removed from your history - Save Video: Save Video Video has been saved: Video has been saved Video has been removed from your saved list: Video has been removed from your saved list Open in YouTube: Open in YouTube