From d3b6563c9ed78f08e02b21b523b26702a43e1dac Mon Sep 17 00:00:00 2001 From: Zeabyte <136193419+Zeabyte@users.noreply.github.com> Date: Mon, 4 Nov 2024 02:35:48 +0100 Subject: [PATCH] Added functionality to export a single playlist (#5779) * Added functionality to export a single playlist * Changed whitespace replacement in export file names to underscore Co-authored-by: PikachuEXE * Added regular expression to replace common forbidden characters in export file name * Optimized regex for replacing illegal characters in file names * Prefer replaceAll over replace * * Make button hidden for online playlist, local playlist w/o video, move it before "remove duplicate" button --------- Co-authored-by: PikachuEXE --- .../components/playlist-info/playlist-info.js | 46 ++++++++++++++++++- .../playlist-info/playlist-info.vue | 7 +++ static/locales/en-US.yaml | 2 + 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/renderer/components/playlist-info/playlist-info.js b/src/renderer/components/playlist-info/playlist-info.js index 6f9ff99bcfd9..03a3ec34ab6b 100644 --- a/src/renderer/components/playlist-info/playlist-info.js +++ b/src/renderer/components/playlist-info/playlist-info.js @@ -10,6 +10,9 @@ import { ctrlFHandler, formatNumber, showToast, + getTodayDateStrLocalTimezone, + writeFileFromDialog, + showSaveDialog, } from '../../helpers/utils' import debounce from 'lodash.debounce' @@ -262,6 +265,13 @@ export default defineComponent({ return this.selectedUserPlaylist.videos.length - this.userPlaylistUniqueVideoIds.size }, + exportPlaylistButtonVisible: function() { + // Only online playlists can be shared + if (!this.isUserPlaylist) { return false } + + return this.videoCount > 0 + }, + deletePlaylistButtonVisible: function() { if (!this.isUserPlaylist) { return false } // Cannot delete during edit @@ -275,7 +285,6 @@ export default defineComponent({ // Only online playlists can be shared if (this.isUserPlaylist) { return false } - // Cannot delete protected playlist return !this.hideSharingActions }, @@ -412,6 +421,41 @@ export default defineComponent({ showToast(this.playlistDeletionDisabledLabel) }, + handlePlaylistExport: async function () { + const dateStr = getTodayDateStrLocalTimezone() + const title = this.selectedUserPlaylist.playlistName.replaceAll(' ', '_').replaceAll(/["%*/:<>?\\|]/g, '_') + const exportFileName = 'freetube-playlist-' + title + '-' + dateStr + '.db' + + const options = { + defaultPath: exportFileName, + filters: [ + { + name: 'Database File', + extensions: ['db'] + } + ] + } + + const data = JSON.stringify(this.selectedUserPlaylist) + '\n' + + // See data-settings.js `promptAndWriteToFile` + const response = await showSaveDialog(options) + if (response.canceled || response.filePath === '') { + // User canceled the save dialog + return + } + + try { + await writeFileFromDialog(response, data) + } catch (writeErr) { + const message = this.$t('Settings.Data Settings.Unable to write file') + showToast(`${message}: ${writeErr}`) + return + } + + showToast(this.$t('User Playlists.The playlist has been successfully exported')) + }, + exitEditMode: function () { this.editMode = false diff --git a/src/renderer/components/playlist-info/playlist-info.vue b/src/renderer/components/playlist-info/playlist-info.vue index 4c8c0cfcf995..3b594f1606ee 100644 --- a/src/renderer/components/playlist-info/playlist-info.vue +++ b/src/renderer/components/playlist-info/playlist-info.vue @@ -169,6 +169,13 @@ theme="secondary" @click="toggleCopyVideosPrompt" /> +