Skip to content

Commit

Permalink
(Replicate) Push up batch 3 of playlist functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
PikachuEXE committed May 18, 2023
1 parent b44b1c5 commit 370b9e2
Show file tree
Hide file tree
Showing 23 changed files with 627 additions and 44 deletions.
12 changes: 11 additions & 1 deletion src/renderer/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import FtPrompt from './components/ft-prompt/ft-prompt.vue'
import FtButton from './components/ft-button/ft-button.vue'
import FtToast from './components/ft-toast/ft-toast.vue'
import FtProgressBar from './components/ft-progress-bar/ft-progress-bar.vue'
import FtPlaylistAddVideoPrompt from './components/ft-playlist-add-video-prompt/ft-playlist-add-video-prompt.vue'
import FtCreatePlaylistPrompt from './components/ft-create-playlist-prompt/ft-create-playlist-prompt.vue'
import { marked } from 'marked'
import { IpcChannels } from '../constants'
import packageDetails from '../../package.json'
Expand All @@ -28,7 +30,9 @@ export default defineComponent({
FtPrompt,
FtButton,
FtToast,
FtProgressBar
FtProgressBar,
FtPlaylistAddVideoPrompt,
FtCreatePlaylistPrompt,
},
data: function () {
return {
Expand Down Expand Up @@ -63,6 +67,12 @@ export default defineComponent({
checkForBlogPosts: function () {
return this.$store.getters.getCheckForBlogPosts
},
showAddToPlaylistPrompt: function () {
return this.$store.getters.getShowAddToPlaylistPrompt
},
showCreatePlaylistPrompt: function () {
return this.$store.getters.getShowCreatePlaylistPrompt
},
windowTitle: function () {
const routeTitle = this.$route.meta.title
if (routeTitle !== 'Channel' && routeTitle !== 'Watch' && routeTitle !== 'Hashtag') {
Expand Down
6 changes: 6 additions & 0 deletions src/renderer/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@
:option-values="externalLinkOpeningPromptValues"
@click="handleExternalLinkOpeningPromptAnswer"
/>
<ft-playlist-add-video-prompt
v-if="showAddToPlaylistPrompt"
/>
<ft-create-playlist-prompt
v-if="showCreatePlaylistPrompt"
/>
<ft-toast />
<ft-progress-bar
v-if="showProgressBar"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
This file is part of FreeTube.
FreeTube is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
FreeTube is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with FreeTube. If not, see <http://www.gnu.org/licenses/>.
*/

/*
* Credit goes to pavelvaravko for making this css.
* https://codepen.io/pavelvaravko/pen/qjojOr
*/

/* select starting stylings ------------------------------*/
.center {
text-align: center;
}

.playlistNameInput {
width: 80%;
max-width: 600px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import Vue from 'vue'
import { mapActions } from 'vuex'
import FtFlexBox from '../ft-flex-box/ft-flex-box.vue'
import FtPrompt from '../ft-prompt/ft-prompt.vue'
import FtButton from '../ft-button/ft-button.vue'
import FtInput from '../ft-input/ft-input.vue'
import FtPlaylistSelector from '../ft-playlist-selector/ft-playlist-selector.vue'

export default Vue.extend({
name: 'FtCreatePlaylistPrompt',
components: {
FtFlexBox,
FtPrompt,
FtButton,
FtInput,
FtPlaylistSelector
},
data: function () {
return {
playlistName: '',
playlistAddVideoPromptValues: [
'save',
'cancel'
],
selectedPlaylists: []
}
},
computed: {
allPlaylists: function () {
return this.$store.getters.getAllPlaylists
},
newPlaylistVideoObject: function () {
return this.$store.getters.getNewPlaylistVideoObject
},
videoImportLength: function () {
return this.newPlaylistVideoObject.videos.length
}
},
mounted: function () {
this.playlistName = this.newPlaylistVideoObject.title
},
methods: {
handleCreatePlaylistPrompt: function (option) {
this.hideCreatePlaylistPrompt()
},

createNewPlaylist: function () {
const videosObject = this.videoImportLength > 0 ? this.newPlaylistVideoObject.videos : []

const playlistObject = {
playlistName: this.playlistName,
protected: false,
removeOnWatched: false,
description: '',
videos: videosObject
}

const nameExists = this.allPlaylists.findIndex((playlist) => {
return playlist.playlistName.toLowerCase() === this.playlistName.toLowerCase()
})

if (this.playlistName === '') {
this.showToast({
message: 'Playlist name cannot be empty. Please input a name.'
})
} else if (nameExists !== -1) {
this.showToast({
message: 'There is already a playlist with this name. Please pick a different name.'
})
} else {
try {
this.addPlaylist(playlistObject)
this.showToast({
message: `Playlist ${this.playlistName} has been successfully created.`
})
} catch (e) {
this.showToast({
message: 'There was an issue with creating the playlist.'
})
console.error(e)
} finally {
this.hideCreatePlaylistPrompt()
}
}
},

...mapActions([
'showToast',
'addPlaylist',
'hideCreatePlaylistPrompt'
])
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<template>
<ft-prompt
@click="handleCreatePlaylistPrompt"
>
<h2 class="center">
New Playlist Name
</h2>
<ft-flex-box>
<ft-input
placeholder="Playlist Name"
:show-action-button="false"
:show-label="false"
:value="playlistName"
class="playlistNameInput"
@input="(input) => playlistName = input"
@click="createNewPlaylist"
/>
</ft-flex-box>
<p
v-if="videoImportLength > 0"
class="center"
>
{{ videoImportLength }} video(s) will also be imported when created
</p>
<ft-flex-box>
<ft-button
label="Create"
@click="createNewPlaylist"
/>
<ft-button
label="Cancel"
@click="handleCreatePlaylistPrompt(null)"
/>
</ft-flex-box>
</ft-prompt>
</template>

<script src="./ft-create-playlist-prompt.js" />
<style scoped src="./ft-create-playlist-prompt.css" />
28 changes: 28 additions & 0 deletions src/renderer/components/ft-list-video/ft-list-video.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ export default defineComponent({
type: String,
default: null
},
playlistType: {
type: String,
default: null
},
playlistIndex: {
type: Number,
default: null
Expand Down Expand Up @@ -101,6 +105,10 @@ export default defineComponent({
return this.$route.name === 'history'
},

inUserPlaylist: function () {
return this.$router.currentRoute.path.includes('playlist') && this.playlistType === 'user'
},

invidiousUrl: function () {
let videoUrl = `${this.currentInvidiousInstance}/watch?v=${this.id}`
// `playlistId` can be undefined
Expand Down Expand Up @@ -590,6 +598,26 @@ export default defineComponent({
this.removeVideo(payload)
},

removeVideoFromPlaylist: function () {
const payload = {
_id: this.playlistId,
videoId: this.id
}

try {
this.removeVideo(payload)
this.$emit('refresh-playlist')
this.showToast({
message: 'Video has been removed'
})
} catch (e) {
this.showToast({
message: 'There was a problem with removing this video'
})
console.error(e)
}
},

togglePlaylistPrompt: function () {
const videoData = {
videoId: this.id,
Expand Down
27 changes: 27 additions & 0 deletions src/renderer/components/ft-list-video/ft-list-video.vue
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,33 @@
:size="appearance === `watchPlaylistItem` ? 14 : 18"
@click="togglePlaylistPrompt"
/>
<ft-icon-button
v-if="inUserPlaylist"
title="Remove from playlist"
icon="trash"
class="trashIcon"
:padding="appearance === `watchPlaylistItem` ? 5 : 6"
:size="appearance === `watchPlaylistItem` ? 14 : 18"
@click="removeVideoFromPlaylist"
/>
<ft-icon-button
v-if="inUserPlaylist"
title="Move video up"
icon="arrow-up"
class="upArrowIcon"
:padding="appearance === `watchPlaylistItem` ? 5 : 6"
:size="appearance === `watchPlaylistItem` ? 14 : 18"
@click="$emit('move-video-up', id)"
/>
<ft-icon-button
v-if="inUserPlaylist"
title="Move video down"
icon="arrow-down"
class="downArrowIcon"
:padding="appearance === `watchPlaylistItem` ? 5 : 6"
:size="appearance === `watchPlaylistItem` ? 14 : 18"
@click="$emit('move-video-down', id)"
/>
<div
v-if="addWatchedStyle"
class="videoWatched"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,30 @@ export default Vue.extend({
},
computed: {
allPlaylists: function () {
return this.$store.getters.getAllPlaylists
const playlists = this.$store.getters.getAllPlaylists
return [].concat(playlists).map((playlist) => {
playlist.title = playlist.playlistName
playlist.type = 'playlist'
playlist.thumbnail = ''
playlist.channelName = ''
playlist.channelId = ''
playlist.playlistId = ''
playlist.videoCount = playlist.videos.length
return playlist
}).sort((a, b) => {
// Sort by favorites, watch later, then alphabetically
if (a._id === 'favorites') {
return -1
} else if (b._id === 'favorites') {
return 1
} else if (a._id === 'watchLater') {
return -1
} else if (b._id === 'watchLater') {
return 1
}

return a.title.localeCompare(b.title, this.locale)
})
},
selectedPlaylistsCount: function () {
return this.selectedPlaylists.length
Expand All @@ -47,7 +70,6 @@ export default Vue.extend({
},
methods: {
handleAddToPlaylistPrompt: function (option) {
console.log(option)
this.hideAddToPlaylistPrompt()
},

Expand Down Expand Up @@ -77,12 +99,24 @@ export default Vue.extend({
addedPlaylists++
}
})

this.showToast({
message: `Video has been added to ${addedPlaylists} playlist(s).`
})
this.handleAddToPlaylistPrompt(null)
},

createNewPlaylist: function () {
this.showCreatePlaylistPrompt({
title: '',
videos: []
})
},

...mapActions([
'addVideo',
'hideAddToPlaylistPrompt'
'hideAddToPlaylistPrompt',
'showCreatePlaylistPrompt',
])
}
})
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
label="Save"
@click="addSelectedToPlaylists"
/>
<ft-button
label="Create New Playlist"
@click="createNewPlaylist"
/>
<ft-button
label="Cancel"
@click="handleAddToPlaylistPrompt(null)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ $watched-transition-duration: 0.5s;
&.grid {
display: flex;
flex-direction: column;
min-width: 245px;
width: 245px;
min-height: 230px;
padding-bottom: 20px;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
class="ft-list-video ft-list-item grid"
:class="{ selected: selected }"
@click="toggleSelection"
@keydown.enter.prevent="toggleSelection"
@keydown.space.prevent="toggleSelection"
>
<div
class="videoThumbnail"
Expand Down
2 changes: 1 addition & 1 deletion src/renderer/components/ft-toast/ft-toast.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
left: 50vw;
transform: translate(-50%, 0);
bottom: 50px;
z-index: 1;
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
Expand Down
Loading

0 comments on commit 370b9e2

Please sign in to comment.