diff --git a/src/renderer/components/playlist-info/playlist-info.js b/src/renderer/components/playlist-info/playlist-info.js index 5b23fa15ce04d..c98be4ed1e186 100644 --- a/src/renderer/components/playlist-info/playlist-info.js +++ b/src/renderer/components/playlist-info/playlist-info.js @@ -110,6 +110,7 @@ export default defineComponent({ editMode: false, showDeletePlaylistPrompt: false, showRemoveVideosOnWatchPrompt: false, + showRemoveDuplicateVideosPrompt: false, newTitle: '', newDescription: '', deletePlaylistPromptValues: [ @@ -165,6 +166,20 @@ export default defineComponent({ this.$t('Cancel') ] }, + removeVideosOnWatchPromptLabelText() { + return this.$tc( + 'User Playlists.Are you sure you want to remove {playlistItemCount} watched videos from this playlist? This cannot be undone', + this.userPlaylistWatchedVideoCount, + { playlistItemCount: this.userPlaylistWatchedVideoCount }, + ) + }, + removeDuplicateVideosPromptLabelText() { + return this.$tc( + 'User Playlists.Are you sure you want to remove {playlistItemCount} duplicate videos from this playlist? This cannot be undone', + this.userPlaylistDuplicateItemCount, + { playlistItemCount: this.userPlaylistDuplicateItemCount }, + ) + }, firstVideoIdExists() { return this.firstVideoId !== '' @@ -211,6 +226,38 @@ export default defineComponent({ return this.isUserPlaylist ? 'user' : '' }, + userPlaylistAnyVideoWatched() { + if (!this.isUserPlaylist) { return false } + + const historyCacheById = this.$store.getters.getHistoryCacheById + return this.selectedUserPlaylist.videos.some((video) => { + return typeof historyCacheById[video.videoId] !== 'undefined' + }) + }, + // `userPlaylistAnyVideoWatched` is faster than this & this is only needed when prompt shown + userPlaylistWatchedVideoCount() { + if (!this.isUserPlaylist) { return false } + + const historyCacheById = this.$store.getters.getHistoryCacheById + return this.selectedUserPlaylist.videos.reduce((count, video) => { + return typeof historyCacheById[video.videoId] !== 'undefined' ? count + 1 : count + }, 0) + }, + + userPlaylistUniqueVideoIds() { + if (!this.isUserPlaylist) { return new Set() } + + return this.selectedUserPlaylist.videos.reduce((set, video) => { + set.add(video.videoId) + return set + }, new Set()) + }, + userPlaylistDuplicateItemCount() { + if (this.userPlaylistUniqueVideoIds.size === 0) { return 0 } + + return this.selectedUserPlaylist.videos.length - this.userPlaylistUniqueVideoIds.size + }, + deletePlaylistButtonVisible: function() { if (!this.isUserPlaylist) { return false } // Cannot delete during edit @@ -334,6 +381,43 @@ export default defineComponent({ this.$emit('exit-edit-mode') }, + handleRemoveDuplicateVideosPromptAnswer(option) { + this.showRemoveDuplicateVideosPrompt = false + if (option !== 'delete') { return } + + const videoIdsAdded = new Set() + const newVideoItems = this.selectedUserPlaylist.videos.reduce((ary, video) => { + if (videoIdsAdded.has(video.videoId)) { return ary } + + ary.push(video) + videoIdsAdded.add(video.videoId) + return ary + }, []) + + const removedVideosCount = this.userPlaylistDuplicateItemCount + if (removedVideosCount === 0) { + showToast(this.$t('User Playlists.SinglePlaylistView.Toast["There were no videos to remove."]')) + return + } + + const playlist = { + playlistName: this.title, + protected: this.selectedUserPlaylist.protected, + description: this.description, + videos: newVideoItems, + _id: this.id, + } + try { + this.updatePlaylist(playlist) + showToast(this.$tc('User Playlists.SinglePlaylistView.Toast.{videoCount} video(s) have been removed', removedVideosCount, { + videoCount: removedVideosCount, + })) + } catch (e) { + showToast(this.$t('User Playlists.SinglePlaylistView.Toast["There was an issue with updating this playlist."]')) + console.error(e) + } + }, + handleRemoveVideosOnWatchPromptAnswer: function (option) { this.showRemoveVideosOnWatchPrompt = false if (option !== 'delete') { return } @@ -346,7 +430,6 @@ export default defineComponent({ if (removedVideosCount === 0) { showToast(this.$t('User Playlists.SinglePlaylistView.Toast["There were no videos to remove."]')) - this.showRemoveVideosOnWatchPrompt = false return } diff --git a/src/renderer/components/playlist-info/playlist-info.vue b/src/renderer/components/playlist-info/playlist-info.vue index a5e6c3b33c707..7c9cc37c0c85a 100644 --- a/src/renderer/components/playlist-info/playlist-info.vue +++ b/src/renderer/components/playlist-info/playlist-info.vue @@ -153,7 +153,14 @@ @click="toggleCopyVideosPrompt" /> + + diff --git a/src/renderer/main.js b/src/renderer/main.js index 4eaa8845c68d5..39276b2d47770 100644 --- a/src/renderer/main.js +++ b/src/renderer/main.js @@ -89,6 +89,7 @@ import { faTimesCircle, faTrash, faUsers, + faUsersSlash, } from '@fortawesome/free-solid-svg-icons' import { faBookmark as farBookmark @@ -187,6 +188,7 @@ library.add( faTimesCircle, faTrash, faUsers, + faUsersSlash, // solid icons farBookmark, diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index c1bf4dec855bb..76f3bb32c368b 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -185,10 +185,12 @@ User Playlists: Cancel: Cancel Edit Playlist Info: Edit Playlist Info Copy Playlist: Copy Playlist + Remove Duplicate Videos: Remove Duplicate Videos Remove Watched Videos: Remove Watched Videos Enable Quick Bookmark With This Playlist: Enable Quick Bookmark With This Playlist Quick Bookmark Enabled: Quick Bookmark Enabled - Are you sure you want to remove all watched videos from this playlist? This cannot be undone: Are you sure you want to remove all watched videos from this playlist? This cannot be undone. + Are you sure you want to remove {playlistItemCount} duplicate videos from this playlist? This cannot be undone: Are you sure you want to remove 1 duplicate video from this playlist? This cannot be undone. | Are you sure you want to remove {playlistItemCount} duplicate videos from this playlist? This cannot be undone. + Are you sure you want to remove {playlistItemCount} watched videos from this playlist? This cannot be undone: Are you sure you want to remove 1 watched video from this playlist? This cannot be undone. | Are you sure you want to remove {playlistItemCount} watched videos from this playlist? This cannot be undone. Delete Playlist: Delete Playlist Cannot delete the quick bookmark target playlist.: Cannot delete the quick bookmark target playlist. Are you sure you want to delete this playlist? This cannot be undone: Are you sure you want to delete this playlist? This cannot be undone.