From 2e64c4f003d76925355da39cf3704456dc6c962e Mon Sep 17 00:00:00 2001 From: Bnyro <bnyro@tutanota.com> Date: Thu, 15 Jun 2023 17:32:32 +0200 Subject: [PATCH] Refactor playlist logic into dedicated functions --- src/components/PlaylistAddModal.vue | 24 +++----- src/components/PlaylistsPage.vue | 86 +++++----------------------- src/components/VideoItem.vue | 7 ++- src/components/WatchVideo.vue | 7 ++- src/main.js | 87 +++++++++++++++++++++++++++++ 5 files changed, 119 insertions(+), 92 deletions(-) diff --git a/src/components/PlaylistAddModal.vue b/src/components/PlaylistAddModal.vue index 3e3a4aac..77df9ac1 100644 --- a/src/components/PlaylistAddModal.vue +++ b/src/components/PlaylistAddModal.vue @@ -23,8 +23,12 @@ export default { ModalComponent, }, props: { + videoInfo: { + type: Object, + required: true, + }, videoId: { - type: String, + type: Object, required: true, }, }, @@ -62,28 +66,14 @@ export default { this.$refs.addButton.disabled = true; this.processing = true; - this.fetchJson(this.authApiUrl() + "/user/playlists/add", null, { - method: "POST", - body: JSON.stringify({ - playlistId: playlistId, - videoId: this.videoId, - }), - headers: { - Authorization: this.getAuthToken(), - "Content-Type": "application/json", - }, - }).then(json => { + this.addVideosToPlaylist(playlistId, [this.videoId], [this.videoInfo]).then(json => { this.setPreference("selectedPlaylist" + this.hashCode(this.authApiUrl()), playlistId); this.$emit("close"); if (json.error) alert(json.error); }); }, async fetchPlaylists() { - this.fetchJson(this.authApiUrl() + "/user/playlists", null, { - headers: { - Authorization: this.getAuthToken(), - }, - }).then(json => { + this.getPlaylists().then(json => { this.playlists = json; }); }, diff --git a/src/components/PlaylistsPage.vue b/src/components/PlaylistsPage.vue index 0dda0efe..58c14543 100644 --- a/src/components/PlaylistsPage.vue +++ b/src/components/PlaylistsPage.vue @@ -1,7 +1,7 @@ <template> - <h2 v-if="authenticated" class="font-bold my-4" v-t="'titles.playlists'" /> + <h2 class="font-bold my-4" v-t="'titles.playlists'" /> - <div v-if="authenticated" class="flex justify-between mb-3"> + <div class="flex justify-between mb-3"> <button v-t="'actions.create_playlist'" class="btn" @click="onCreatePlaylist" /> <div class="flex"> <button @@ -63,7 +63,7 @@ v-if="playlistToDelete == playlist.id" :message="$t('actions.delete_playlist_confirm')" @close="playlistToDelete = null" - @confirm="deletePlaylist(playlist.id)" + @confirm="onDeletePlaylist(playlist.id)" /> </div> </div> @@ -115,7 +115,7 @@ export default { }; }, mounted() { - if (this.authenticated) this.fetchPlaylists(); + this.fetchPlaylists(); this.loadPlaylistBookmarks(); }, activated() { @@ -123,11 +123,7 @@ export default { }, methods: { fetchPlaylists() { - this.fetchJson(this.authApiUrl() + "/user/playlists", null, { - headers: { - Authorization: this.getAuthToken(), - }, - }).then(json => { + this.getPlaylists().then(json => { this.playlists = json; }); }, @@ -141,50 +137,21 @@ export default { const newName = this.newPlaylistName; const newDescription = this.newPlaylistDescription; if (newName != selectedPlaylist.name) { - this.fetchJson(this.authApiUrl() + "/user/playlists/rename", null, { - method: "POST", - body: JSON.stringify({ - playlistId: selectedPlaylist.id, - newName: newName, - }), - headers: { - Authorization: this.getAuthToken(), - "Content-Type": "application/json", - }, - }).then(json => { + this.renamePlaylist(selectedPlaylist.id, newName).then(json => { if (json.error) alert(json.error); else selectedPlaylist.name = newName; }); } if (newDescription != selectedPlaylist.description) { - this.fetchJson(this.authApiUrl() + "/user/playlists/description", null, { - method: "PATCH", - body: JSON.stringify({ - playlistId: selectedPlaylist.id, - description: newDescription, - }), - headers: { - Authorization: this.getAuthToken(), - "Content-Type": "application/json", - }, - }).then(json => { + this.changePlaylistDescription(selectedPlaylist.id, newDescription).then(json => { if (json.error) alert(json.error); else selectedPlaylist.description = newDescription; }); } this.playlistToEdit = null; }, - deletePlaylist(id) { - this.fetchJson(this.authApiUrl() + "/user/playlists/delete", null, { - method: "POST", - body: JSON.stringify({ - playlistId: id, - }), - headers: { - Authorization: this.getAuthToken(), - "Content-Type": "application/json", - }, - }).then(json => { + onDeletePlaylist(id) { + this.deletePlaylist(id).then(json => { if (json.error) alert(json.error); else this.playlists = this.playlists.filter(playlist => playlist.id !== id); }); @@ -198,19 +165,6 @@ export default { else this.fetchPlaylists(); }); }, - async createPlaylist(name) { - let json = await this.fetchJson(this.authApiUrl() + "/user/playlists/create", null, { - method: "POST", - body: JSON.stringify({ - name: name, - }), - headers: { - Authorization: this.getAuthToken(), - "Content-Type": "application/json", - }, - }); - return json; - }, async exportPlaylists() { if (!this.playlists) return; let json = { @@ -223,8 +177,8 @@ export default { this.download(JSON.stringify(json), "playlists.json", "application/json"); }, async fetchPlaylistJson(playlistId) { - let playlist = await this.fetchJson(this.authApiUrl() + "/playlists/" + playlistId); - let playlistJson = { + let playlist = await this.getPlaylist(playlistId); + return { name: playlist.name, // possible other types: history, watch later, ... type: "playlist", @@ -233,7 +187,6 @@ export default { // list of the videos, starting with "https://youtube.com" to clarify that those are YT videos videos: playlist.relatedStreams.map(stream => "https://youtube.com" + stream.url), }; - return playlistJson; }, async importPlaylists() { const files = this.$refs.fileSelector.files; @@ -252,8 +205,8 @@ export default { alert(this.$t("actions.no_valid_playlists")); return; } - for (var i = 0; i < playlists.length; i++) { - tasks.push(this.createPlaylistWithVideos(playlists[i])); + for (let playlist of playlists) { + tasks.push(this.createPlaylistWithVideos(playlist)); } // CSV from Google Takeout } else if (file.name.slice(-4).toLowerCase() == ".csv") { @@ -277,19 +230,6 @@ export default { let videoIds = playlist.videos.map(url => url.substr(-11)); await this.addVideosToPlaylist(newPlaylist.playlistId, videoIds); }, - async addVideosToPlaylist(playlistId, videoIds) { - await this.fetchJson(this.authApiUrl() + "/user/playlists/add", null, { - method: "POST", - body: JSON.stringify({ - playlistId: playlistId, - videoIds: videoIds, - }), - headers: { - Authorization: this.getAuthToken(), - "Content-Type": "application/json", - }, - }); - }, async loadPlaylistBookmarks() { if (!window.db) return; var tx = window.db.transaction("playlist_bookmarks", "readonly"); diff --git a/src/components/VideoItem.vue b/src/components/VideoItem.vue index 918ebb3f..702814e0 100644 --- a/src/components/VideoItem.vue +++ b/src/components/VideoItem.vue @@ -124,7 +124,12 @@ @confirm="removeVideo(item.url.substr(-11))" :message="$t('actions.delete_playlist_video_confirm')" /> - <PlaylistAddModal v-if="showModal" :video-id="item.url.substr(-11)" @close="showModal = !showModal" /> + <PlaylistAddModal + v-if="showModal" + :video-id="item.url.substr(-11)" + video-info="item" + @close="showModal = !showModal" + /> </div> </div> </div> diff --git a/src/components/WatchVideo.vue b/src/components/WatchVideo.vue index 2f34e6e2..6deff7f9 100644 --- a/src/components/WatchVideo.vue +++ b/src/components/WatchVideo.vue @@ -78,7 +78,12 @@ <!-- Verified Badge --> <font-awesome-icon class="ml-1" v-if="video.uploaderVerified" icon="check" /> </div> - <PlaylistAddModal v-if="showModal" :video-id="getVideoId()" @close="showModal = !showModal" /> + <PlaylistAddModal + v-if="showModal" + :video-id="getVideoId()" + :video-info="video" + @close="showModal = !showModal" + /> <ShareModal v-if="showShareModal" :video-id="getVideoId()" diff --git a/src/main.js b/src/main.js index 71b916d4..a1ffb6d3 100644 --- a/src/main.js +++ b/src/main.js @@ -292,6 +292,93 @@ const mixin = { var store = tx.objectStore("channel_groups"); store.delete(groupName); }, + async getPlaylists() { + return await this.fetchJson(this.authApiUrl() + "/user/playlists", null, { + headers: { + Authorization: this.getAuthToken(), + }, + }); + }, + async getPlaylist(playlistId) { + return await this.fetchJson(this.authApiUrl() + "/playlists/" + playlistId); + }, + async createPlaylist(name) { + return await this.fetchJson(this.authApiUrl() + "/user/playlists/create", null, { + method: "POST", + body: JSON.stringify({ + name: name, + }), + headers: { + Authorization: this.getAuthToken(), + "Content-Type": "application/json", + }, + }); + }, + async deletePlaylist(playlistId) { + return await this.fetchJson(this.authApiUrl() + "/user/playlists/delete", null, { + method: "POST", + body: JSON.stringify({ + playlistId: playlistId, + }), + headers: { + Authorization: this.getAuthToken(), + "Content-Type": "application/json", + }, + }); + }, + async renamePlaylist(playlistId, newName) { + return await this.fetchJson(this.authApiUrl() + "/user/playlists/rename", null, { + method: "POST", + body: JSON.stringify({ + playlistId: playlistId, + newName: newName, + }), + headers: { + Authorization: this.getAuthToken(), + "Content-Type": "application/json", + }, + }); + }, + async changePlaylistDescription(playlistId, newDescription) { + return await this.fetchJson(this.authApiUrl() + "/user/playlists/description", null, { + method: "PATCH", + body: JSON.stringify({ + playlistId: playlistId, + description: newDescription, + }), + headers: { + Authorization: this.getAuthToken(), + "Content-Type": "application/json", + }, + }); + }, + async addVideosToPlaylist(playlistId, videoIds, videoInfos) { + if (videoInfos == "hallo") return; //TODO, only needed for local vids + return await this.fetchJson(this.authApiUrl() + "/user/playlists/add", null, { + method: "POST", + body: JSON.stringify({ + playlistId: playlistId, + videoIds: videoIds, + }), + headers: { + Authorization: this.getAuthToken(), + "Content-Type": "application/json", + }, + }); + }, + async removeVideoFromPlaylist(playlistId, videoId) { + return await this.fetchJson(this.authApiUrl() + "/user/playlists/add", null, { + method: "POST", + body: JSON.stringify({ + playlistId: playlistId, + videoId: videoId, + }), + headers: { + Authorization: this.getAuthToken(), + "Content-Type": "application/json", + }, + }); + }, }, computed: { authenticated(_this) {