diff --git a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.css b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.css index aa18554033106..ddcd76c767ac3 100644 --- a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.css +++ b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.css @@ -24,16 +24,29 @@ .optionsRow { display: grid; - grid-template-columns: repeat(2, 1fr); - grid-template-rows: 1fr; + grid-template-columns: repeat(auto-fit, minmax(100px, 1fr)); + align-items: center; +} + +.tightOptions { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(100px, max-content)); + column-gap: 16px; align-items: center; } @media only screen and (width <= 800px) { .optionsRow { - /* Switch to 2 rows from 2 columns */ + /* Switch to rows from columns */ grid-template-columns: auto; - grid-template-rows: auto auto; + grid-template-rows: repeat(auto-fit, auto); + align-items: stretch; + } + + .tightOptions { + /* Switch to rows from columns */ + grid-template-columns: auto; + grid-template-rows: repeat(auto-fit, auto); align-items: stretch; } } @@ -51,7 +64,11 @@ overflow-y: scroll; } -.playlist-selector-container { +.playlist-selector-container:not(.disabled) { /* Make them look selectable */ cursor: pointer; } + +.playlist-selector-container.disabled { + opacity: 0.5; +} diff --git a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js index 3e51d789a959f..c1808e6a52ed9 100644 --- a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js +++ b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.js @@ -45,6 +45,7 @@ export default defineComponent({ updateQueryDebounce: function() {}, lastShownAt: Date.now(), sortBy: SORT_BY_VALUES.LatestUpdatedFirst, + addingDuplicateVideosEnabled: false, } }, computed: { @@ -111,6 +112,9 @@ export default defineComponent({ toBeAddedToPlaylistVideoList: function () { return this.$store.getters.getToBeAddedToPlaylistVideoList }, + toBeAddedToPlaylistVideoIdList: function () { + return this.toBeAddedToPlaylistVideoList.map((v) => v.videoId) + }, newPlaylistDefaultProperties: function () { return this.$store.getters.getNewPlaylistDefaultProperties }, @@ -161,6 +165,23 @@ export default defineComponent({ sortBySelectValues() { return Object.values(SORT_BY_VALUES) }, + + playlistIdsContainingVideosToBeAdded() { + const ids = [] + + this.allPlaylists.forEach((playlist) => { + const playlistVideoIdSet = playlist.videos.reduce((s, v) => s.add(v.videoId), new Set()) + + if (this.toBeAddedToPlaylistVideoIdList.every((vid) => playlistVideoIdSet.has(vid))) { + ids.push(playlist._id) + } + }) + + return ids + }, + anyPlaylistContainsVideosToBeAdded() { + return this.playlistIdsContainingVideosToBeAdded.length > 0 + }, }, watch: { allPlaylistsLength(val, oldVal) { @@ -202,6 +223,16 @@ export default defineComponent({ // due to enter key press in CreatePlaylistPrompt nextTick(() => this.$refs.searchBar.focus()) }, + + addingDuplicateVideosEnabled(val) { + if (val) { return } + + // Only care when addingDuplicateVideosEnabled disabled + // Remove disabled playlists + this.selectedPlaylistIdList = this.selectedPlaylistIdList.filter(playlistId => { + return !this.playlistIdsContainingVideosToBeAdded.includes(playlistId) + }) + }, }, mounted: function () { this.updateQueryDebounce = debounce(this.updateQuery, 500) @@ -238,10 +269,16 @@ export default defineComponent({ const playlist = this.allPlaylists.find((list) => list._id === selectedPlaylistId) if (playlist == null) { return } + // Use [].concat to avoid `do not mutate vuex store state outside mutation handlers` + let videosToBeAdded = [].concat(this.toBeAddedToPlaylistVideoList) + if (!this.addingDuplicateVideosEnabled) { + const playlistVideoIds = playlist.videos.map((v) => v.videoId) + videosToBeAdded = videosToBeAdded.filter((v) => !playlistVideoIds.includes(v.videoId)) + } + this.addVideos({ _id: playlist._id, - // Use [].concat to avoid `do not mutate vuex store state outside mutation handlers` - videos: [].concat(this.toBeAddedToPlaylistVideoList), + videos: videosToBeAdded, }) addedPlaylistIds.add(playlist._id) // Update playlist's `lastUpdatedAt` @@ -281,6 +318,12 @@ export default defineComponent({ getIconForSortPreference: (s) => getIconForSortPreference(s), + playlistDisabled(playlistId) { + if (this.addingDuplicateVideosEnabled) { return false } + + return this.playlistIdsContainingVideosToBeAdded.includes(playlistId) + }, + ...mapActions([ 'addVideos', 'updatePlaylist', diff --git a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.vue b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.vue index 3ab9a13fa907b..25116cc1f6708 100644 --- a/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.vue +++ b/src/renderer/components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.vue @@ -27,12 +27,25 @@
diff --git a/static/locales/en-US.yaml b/static/locales/en-US.yaml index 3517fb1071f9a..2ea839828900c 100644 --- a/static/locales/en-US.yaml +++ b/static/locales/en-US.yaml @@ -216,9 +216,12 @@ User Playlists: Select a playlist to add your N videos to: 'Select a playlist to add your video to | Select a playlist to add your {videoCount} videos to' N playlists selected: '{playlistCount} Selected' Search in Playlists: Search in Playlists + Allow Adding Duplicate Video(s): Allow Adding Duplicate Video(s) Save: Save - Added {count} Times: 'Added {count} Time | Added {count} Times' + Added {count} Times: 'Already Added | Added {count} Times' + "{videoCount}/{totalVideoCount} Videos Will Be Added": '{videoCount}/{totalVideoCount} Videos Will Be Added' + "{videoCount}/{totalVideoCount} Videos Already Added": '{videoCount}/{totalVideoCount} Videos Already Added' Toast: You haven't selected any playlist yet.: You haven't selected any playlist yet. diff --git a/static/locales/en_GB.yaml b/static/locales/en_GB.yaml index 52d9655e17f2a..54ac1924e4c13 100644 --- a/static/locales/en_GB.yaml +++ b/static/locales/en_GB.yaml @@ -190,7 +190,7 @@ User Playlists: playlists Select a playlist to add your N videos to: Select a playlist to add your video to | Select a playlist to add your {videoCount} videos to - Added {count} Times: Added {count} time | Added {count} times + Added {count} Times: Already Added | Added {count} times CreatePlaylistPrompt: New Playlist Name: New Playlist name Create: Create