Initial Playlist implementation. Functions like basic favorites list
This commit is contained in:
parent
7505d8cf90
commit
659415edc3
|
@ -88,6 +88,7 @@ export default Vue.extend({
|
|||
this.$store.dispatch('grabUserSettings')
|
||||
this.$store.dispatch('grabHistory')
|
||||
this.$store.dispatch('grabAllProfiles', this.$t('Profile.All Channels'))
|
||||
this.$store.dispatch('grabAllPlaylists')
|
||||
this.$store.commit('setUsingElectron', useElectron)
|
||||
this.checkThemeSettings()
|
||||
this.checkLocale()
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
&:active
|
||||
background-color: var(--accent-color-active)
|
||||
|
||||
&.favorite
|
||||
color: var(--favorite-icon-color)
|
||||
|
||||
.iconDropdown
|
||||
display: none
|
||||
position: absolute
|
||||
|
|
|
@ -165,6 +165,22 @@ export default Vue.extend({
|
|||
|
||||
addWatchedStyle: function () {
|
||||
return this.watched && !this.inHistory
|
||||
},
|
||||
|
||||
favoritesPlaylist: function () {
|
||||
return this.$store.getters.getFavorites
|
||||
},
|
||||
|
||||
inFavoritesPlaylist: function () {
|
||||
const index = this.favoritesPlaylist.videos.findIndex((video) => {
|
||||
return video.videoId === this.id
|
||||
})
|
||||
|
||||
return index !== -1
|
||||
},
|
||||
|
||||
favoriteIconTheme: function () {
|
||||
return this.inFavoritesPlaylist ? 'base favorite' : 'base'
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
|
@ -173,10 +189,11 @@ export default Vue.extend({
|
|||
},
|
||||
methods: {
|
||||
toggleSave: function () {
|
||||
console.log('TODO: ft-list-video method toggleSave')
|
||||
this.showToast({
|
||||
message: this.$t('Saving videos are currently not available. Please wait for a future update')
|
||||
})
|
||||
if (this.inFavoritesPlaylist) {
|
||||
this.removeFromPlaylist()
|
||||
} else {
|
||||
this.addToPlaylist()
|
||||
}
|
||||
},
|
||||
|
||||
handleOptionsClick: function (option) {
|
||||
|
@ -396,11 +413,54 @@ export default Vue.extend({
|
|||
this.watched = false
|
||||
},
|
||||
|
||||
addToPlaylist: function () {
|
||||
const videoData = {
|
||||
videoId: this.id,
|
||||
title: this.title,
|
||||
author: this.channelName,
|
||||
authorId: this.channelId,
|
||||
published: '',
|
||||
description: this.description,
|
||||
viewCount: this.viewCount,
|
||||
lengthSeconds: this.data.lengthSeconds,
|
||||
timeAdded: new Date().getTime(),
|
||||
isLive: false,
|
||||
paid: false,
|
||||
type: 'video'
|
||||
}
|
||||
|
||||
const payload = {
|
||||
playlistName: 'Favorites',
|
||||
videoData: videoData
|
||||
}
|
||||
|
||||
this.addVideo(payload)
|
||||
|
||||
this.showToast({
|
||||
message: this.$t('Video.Video has been saved')
|
||||
})
|
||||
},
|
||||
|
||||
removeFromPlaylist: function () {
|
||||
const payload = {
|
||||
playlistName: 'Favorites',
|
||||
videoId: this.id
|
||||
}
|
||||
|
||||
this.removeVideo(payload)
|
||||
|
||||
this.showToast({
|
||||
message: this.$t('Video.Video has been removed from your saved list')
|
||||
})
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'showToast',
|
||||
'toLocalePublicationString',
|
||||
'updateHistory',
|
||||
'removeFromHistory'
|
||||
'removeFromHistory',
|
||||
'addVideo',
|
||||
'removeVideo'
|
||||
])
|
||||
}
|
||||
})
|
||||
|
|
|
@ -32,13 +32,13 @@
|
|||
</div>
|
||||
<ft-icon-button
|
||||
v-if="!isLive"
|
||||
:title="$t('Video.Save Video')"
|
||||
icon="star"
|
||||
class="favoritesIcon"
|
||||
theme="base"
|
||||
:theme="favoriteIconTheme"
|
||||
:padding="appearance === `watchPlaylistItem` ? 5 : 6"
|
||||
:size="appearance === `watchPlaylistItem` ? 14 : 18"
|
||||
:class="{ favorited: isFavorited }"
|
||||
@click="toggleSave(id)"
|
||||
@click="toggleSave"
|
||||
/>
|
||||
<div
|
||||
v-if="addWatchedStyle"
|
||||
|
|
|
@ -86,6 +86,10 @@ export default Vue.extend({
|
|||
theatrePossible: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
lengthSeconds: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
|
@ -131,6 +135,22 @@ export default Vue.extend({
|
|||
return this.$store.getters.getHideVideoViews
|
||||
},
|
||||
|
||||
favoritesPlaylist: function () {
|
||||
return this.$store.getters.getFavorites
|
||||
},
|
||||
|
||||
inFavoritesPlaylist: function () {
|
||||
const index = this.favoritesPlaylist.videos.findIndex((video) => {
|
||||
return video.videoId === this.id
|
||||
})
|
||||
|
||||
return index !== -1
|
||||
},
|
||||
|
||||
favoriteIconTheme: function () {
|
||||
return this.inFavoritesPlaylist ? 'base favorite' : 'base'
|
||||
},
|
||||
|
||||
downloadLinkNames: function () {
|
||||
return this.downloadLinks.map((download) => {
|
||||
return download.label
|
||||
|
@ -208,6 +228,14 @@ export default Vue.extend({
|
|||
this.$router.push({ path: `/channel/${this.channelId}` })
|
||||
},
|
||||
|
||||
toggleSave: function () {
|
||||
if (this.inFavoritesPlaylist) {
|
||||
this.removeFromPlaylist()
|
||||
} else {
|
||||
this.addToPlaylist()
|
||||
}
|
||||
},
|
||||
|
||||
handleSubscription: function () {
|
||||
if (this.channelId === '') {
|
||||
return
|
||||
|
@ -303,9 +331,48 @@ export default Vue.extend({
|
|||
shell.openExternal(url)
|
||||
},
|
||||
|
||||
addToPlaylist: function () {
|
||||
const videoData = {
|
||||
videoId: this.id,
|
||||
title: this.title,
|
||||
author: this.channelName,
|
||||
authorId: this.channelId,
|
||||
published: '',
|
||||
description: this.description,
|
||||
viewCount: this.viewCount,
|
||||
lengthSeconds: this.lengthSeconds,
|
||||
timeAdded: new Date().getTime(),
|
||||
isLive: false,
|
||||
paid: false,
|
||||
type: 'video'
|
||||
}
|
||||
|
||||
const payload = {
|
||||
playlistName: 'Favorites',
|
||||
videoData: videoData
|
||||
}
|
||||
|
||||
this.addVideo(payload)
|
||||
|
||||
this.showToast({
|
||||
message: this.$t('Video.Video has been marked as watched')
|
||||
})
|
||||
},
|
||||
|
||||
removeFromPlaylist: function () {
|
||||
const payload = {
|
||||
playlistName: 'Favorites',
|
||||
videoId: this.id
|
||||
}
|
||||
|
||||
this.removeVideo(payload)
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'showToast',
|
||||
'updateProfile'
|
||||
'updateProfile',
|
||||
'addVideo',
|
||||
'removeVideo'
|
||||
])
|
||||
}
|
||||
})
|
||||
|
|
|
@ -62,6 +62,14 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="videoOptions">
|
||||
<ft-icon-button
|
||||
v-if="!isUpcoming"
|
||||
:title="$t('Video.Save Video')"
|
||||
icon="star"
|
||||
class="option"
|
||||
:theme="favoriteIconTheme"
|
||||
@click="toggleSave"
|
||||
/>
|
||||
<ft-icon-button
|
||||
v-if="theatrePossible"
|
||||
:title="$t('Toggle Theatre Mode')"
|
||||
|
|
|
@ -4,14 +4,19 @@ let dbLocation
|
|||
|
||||
if (window && window.process && window.process.type === 'renderer') {
|
||||
// Electron is being used
|
||||
let dbLocation = localStorage.getItem('dbLocation')
|
||||
// let dbLocation = localStorage.getItem('dbLocation')
|
||||
//
|
||||
// if (dbLocation === null) {
|
||||
// const electron = require('electron')
|
||||
// dbLocation = electron.remote.app.getPath('userData')
|
||||
// }
|
||||
//
|
||||
// dbLocation += '/playlists.db'
|
||||
|
||||
if (dbLocation === null) {
|
||||
const electron = require('electron')
|
||||
dbLocation = electron.remote.app.getPath('userData')
|
||||
}
|
||||
const electron = require('electron')
|
||||
dbLocation = electron.remote.app.getPath('userData')
|
||||
|
||||
dbLocation += '/playlists.db'
|
||||
dbLocation = dbLocation + '/playlists.db'
|
||||
} else {
|
||||
dbLocation = 'playlists.db'
|
||||
}
|
||||
|
@ -24,12 +29,12 @@ const playlistDb = new Datastore({
|
|||
const state = {
|
||||
playlists: [
|
||||
{
|
||||
_id: 'favorites',
|
||||
playlistName: 'Favorites',
|
||||
protected: true,
|
||||
videos: []
|
||||
},
|
||||
{
|
||||
_id: 'watchLater',
|
||||
playlistName: 'WatchLater',
|
||||
protected: true,
|
||||
removeOnWatched: true,
|
||||
videos: []
|
||||
|
@ -64,7 +69,7 @@ const actions = {
|
|||
})
|
||||
},
|
||||
addVideo ({ commit }, payload) {
|
||||
playlistDb.update({ _id: payload.playlistId }, { $push: { videos: payload.videoId } }, { upsert: true }, err => {
|
||||
playlistDb.update({ playlistName: payload.playlistName }, { $push: { videos: payload.videoData } }, { upsert: true }, err => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
} else {
|
||||
|
@ -81,12 +86,17 @@ const actions = {
|
|||
}
|
||||
})
|
||||
},
|
||||
grabAllPlaylists({ commit }) {
|
||||
playlistDb.getAllData((err, payload) => {
|
||||
grabAllPlaylists({ commit, dispatch }) {
|
||||
playlistDb.find({}, (err, payload) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
} else {
|
||||
commit('setAllPlaylists', payload)
|
||||
if (payload.length === 0) {
|
||||
commit('setAllPlaylists', state.playlists)
|
||||
dispatch('addPlaylists', payload)
|
||||
} else {
|
||||
commit('setAllPlaylists', payload)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -99,12 +109,12 @@ const actions = {
|
|||
}
|
||||
})
|
||||
},
|
||||
removeAllVideos ({ commit }, playlistId) {
|
||||
playlistDb.update({ _id: playlistId }, { $set: { videos: [] } }, { upsert: true }, err => {
|
||||
removeAllVideos ({ commit }, playlistName) {
|
||||
playlistDb.update({ playlistName: playlistName }, { $set: { videos: [] } }, { upsert: true }, err => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
} else {
|
||||
commit('removeAllVideos', playlistId)
|
||||
commit('removeAllVideos', playlistName)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -127,7 +137,7 @@ const actions = {
|
|||
})
|
||||
},
|
||||
removeVideo ({ commit }, payload) {
|
||||
playlistDb.update({ _id: payload.playlistId }, { $pull: { videos: payload.videoId } }, { upsert: true }, err => {
|
||||
playlistDb.update({ playlistName: payload.playlistName }, { $pull: { videos: { videoId: payload.videoId } } }, { upsert: true }, (err, numRemoved) => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
} else {
|
||||
|
@ -136,7 +146,7 @@ const actions = {
|
|||
})
|
||||
},
|
||||
removeVideos ({ commit }, payload) {
|
||||
playlistDb.update({ _id: payload.playlistId }, { $pull: { videos: { $in: payload.videoIds } } }, { upsert: true }, err => {
|
||||
playlistDb.update({ _id: payload.playlistName }, { $pull: { videos: { $in: payload.videoId } } }, { upsert: true }, err => {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
} else {
|
||||
|
@ -154,9 +164,9 @@ const mutations = {
|
|||
state.playlists = state.playlists.concat(payload)
|
||||
},
|
||||
addVideo (state, payload) {
|
||||
const playlist = state.playlists.find(playlist => playlist._id === payload.playlistId)
|
||||
const playlist = state.playlists.find(playlist => playlist.playlistName === payload.playlistName)
|
||||
if (playlist) {
|
||||
playlist.videos.push(payload.videoId)
|
||||
playlist.videos.push(payload.videoData)
|
||||
}
|
||||
},
|
||||
addVideos (state, payload) {
|
||||
|
@ -168,22 +178,22 @@ const mutations = {
|
|||
removeAllPlaylists (state) {
|
||||
state.playlists = state.playlists.filter(playlist => playlist.protected !== true)
|
||||
},
|
||||
removeAllVideos (state, playlistId) {
|
||||
const playlist = state.playlists.find(playlist => playlist._id === playlistId)
|
||||
removeAllVideos (state, playlistName) {
|
||||
const playlist = state.playlists.find(playlist => playlist.playlistName === playlistName)
|
||||
if (playlist) {
|
||||
playlist.videos = []
|
||||
}
|
||||
},
|
||||
removeVideo (state, payload) {
|
||||
const playlist = state.playlists.find(playlist => playlist._id === payload.playlistId)
|
||||
if (playlist) {
|
||||
playlist.videos = playlist.videos.filter(video => video !== payload.videoId)
|
||||
const playlist = state.playlists.findIndex(playlist => playlist.playlistName === payload.playlistName)
|
||||
if (playlist !== -1) {
|
||||
state.playlists[playlist].videos = state.playlists[playlist].videos.filter(video => video.videoId !== payload.videoId)
|
||||
}
|
||||
},
|
||||
removeVideos (state, payload) {
|
||||
const playlist = state.playlists.find(playlist => playlist._id === payload.playlistId)
|
||||
if (playlist) {
|
||||
playlist.videos = playlist.videos.filter(video => payload.videoIds.indexOf(video) === -1)
|
||||
const playlist = state.playlists.findIndex(playlist => playlist._id === payload.playlistId)
|
||||
if (playlist !== -1) {
|
||||
playlist.videos = playlist.videos.filter(video => payload.videoId.indexOf(video) === -1)
|
||||
}
|
||||
},
|
||||
removePlaylist (state, playlistId) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
--bg-color: #f1f1f1;
|
||||
--link-color: var(--accent-color);
|
||||
--link-visited-color: var(--accent-color-visited);
|
||||
--favorite-icon-color: #FFD600;
|
||||
--card-bg-color: #FFFFFF;
|
||||
--secondary-card-bg-color: #eeeeee;
|
||||
--scrollbar-color: #CCCCCC;
|
||||
|
@ -32,6 +33,7 @@
|
|||
--bg-color: #212121;
|
||||
--link-color: var(--accent-color);
|
||||
--link-visited-color: var(--accent-color-visited);
|
||||
--favorite-icon-color: #FFEA00;
|
||||
--card-bg-color: #303030;
|
||||
--secondary-card-bg-color: rgba(0, 0, 0, 0.75);
|
||||
--scrollbar-color: #414141;
|
||||
|
@ -55,6 +57,7 @@
|
|||
--bg-color: #000000;
|
||||
--link-color: var(--accent-color);
|
||||
--link-visited-color: var(--accent-color-visited);
|
||||
--favorite-icon-color: #FFEA00;
|
||||
--card-bg-color: #000000;
|
||||
--secondary-card-bg-color: rgba(0, 0, 0, 0.75);
|
||||
--scrollbar-color: #515151;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import Vue from 'vue'
|
||||
import FtCard from '../../components/ft-card/ft-card.vue'
|
||||
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
|
||||
import FtTooltip from '../../components/ft-tooltip/ft-tooltip.vue'
|
||||
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
||||
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
|
||||
|
||||
export default Vue.extend({
|
||||
|
@ -8,8 +10,48 @@ export default Vue.extend({
|
|||
components: {
|
||||
'ft-card': FtCard,
|
||||
'ft-flex-box': FtFlexBox,
|
||||
'ft-tooltip': FtTooltip,
|
||||
'ft-loader': FtLoader,
|
||||
'ft-element-list': FtElementList
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
isLoading: false,
|
||||
dataLimit: 100
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
favoritesPlaylist: function () {
|
||||
return this.$store.getters.getFavorites
|
||||
},
|
||||
|
||||
activeData: function () {
|
||||
if (this.favoritesPlaylist.videos.length < this.dataLimit) {
|
||||
return this.favoritesPlaylist.videos
|
||||
} else {
|
||||
return this.favoritesPlaylist.videos.slice(0, this.dataLimit)
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeData() {
|
||||
this.isLoading = true
|
||||
setTimeout(() => {
|
||||
this.isLoading = false
|
||||
}, 100)
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
const limit = sessionStorage.getItem('favoritesLimit')
|
||||
|
||||
if (limit !== null) {
|
||||
this.dataLimit = limit
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
increaseLimit: function () {
|
||||
this.dataLimit += 100
|
||||
sessionStorage.setItem('favoritesLimit', this.dataLimit)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,12 +1,42 @@
|
|||
<template>
|
||||
<div>
|
||||
<ft-card class="card">
|
||||
<h3>{{ $t("User Playlists.Your Playlists") }}</h3>
|
||||
<ft-flex-box>
|
||||
<ft-loader
|
||||
v-if="isLoading"
|
||||
:fullscreen="true"
|
||||
/>
|
||||
<ft-card
|
||||
v-else
|
||||
class="card"
|
||||
>
|
||||
<h3>
|
||||
{{ $t("User Playlists.Your Playlists") }}
|
||||
<ft-tooltip
|
||||
class="selectTooltip"
|
||||
position="bottom"
|
||||
:tooltip="$t('User Playlists.Playlist Message')"
|
||||
/>
|
||||
</h3>
|
||||
<ft-flex-box
|
||||
v-if="activeData.length === 0"
|
||||
>
|
||||
<p class="message">
|
||||
{{ $t("This part of the app is not ready yet. Come back later when progress has been made.") }}
|
||||
{{ $t("User Playlists['Your saved videos are empty. Click on the save button on the corner of a video to have it listed here']") }}
|
||||
</p>
|
||||
</ft-flex-box>
|
||||
<ft-element-list
|
||||
v-else
|
||||
:data="activeData"
|
||||
/>
|
||||
<ft-flex-box
|
||||
v-if="activeData.length < favoritesPlaylist.videos.length"
|
||||
>
|
||||
<ft-button
|
||||
label="Load More"
|
||||
background-color="var(--primary-color)"
|
||||
text-color="var(--text-with-main-color)"
|
||||
@click="increaseLimit"
|
||||
/>
|
||||
</ft-flex-box>
|
||||
</ft-card>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
:download-links="downloadLinks"
|
||||
:watching-playlist="watchingPlaylist"
|
||||
:theatre-possible="theatrePossible"
|
||||
:length-seconds="videoLengthSeconds"
|
||||
class="watchVideo"
|
||||
:class="{ theatreWatchVideo: useTheatreMode }"
|
||||
@theatre-mode="toggleTheatreMode"
|
||||
|
|
|
@ -86,6 +86,8 @@ Most Popular: Most Popular
|
|||
Playlists: Playlists
|
||||
User Playlists:
|
||||
Your Playlists: Your Playlists
|
||||
Playlist Message: This page is not reflective of fully working playlists. It only lists videos that you have saved or favorited. When the work has finished, all videos currently here will be migrated to a 'Favorites' playlist.
|
||||
Your saved videos are empty. Click on the save button on the corner of a video to have it listed here: Your saved videos are empty. Click on the save button on the corner of a video to have it listed here
|
||||
History:
|
||||
# On History Page
|
||||
History: History
|
||||
|
@ -368,6 +370,9 @@ Video:
|
|||
Remove From History: Remove From History
|
||||
Video has been marked as watched: Video has been marked as watched
|
||||
Video has been removed from your history: Video has been removed from your history
|
||||
Save Video: Save Video
|
||||
Video has been saved: Video has been saved
|
||||
Video has been removed from your saved list: Video has been removed from your saved list
|
||||
Open in YouTube: Open in YouTube
|
||||
Copy YouTube Link: Copy YouTube Link
|
||||
Open YouTube Embedded Player: Open YouTube Embedded Player
|
||||
|
|
Loading…
Reference in New Issue