Implement History and jump to last watched time progress
This commit is contained in:
parent
6e5e1e0542
commit
2133a10efa
|
@ -31,6 +31,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.$store.dispatch('grabUserSettings')
|
this.$store.dispatch('grabUserSettings')
|
||||||
|
this.$store.dispatch('grabHistory')
|
||||||
this.$store.commit('setUsingElectron', useElectron)
|
this.$store.commit('setUsingElectron', useElectron)
|
||||||
this.checkThemeSettings()
|
this.checkThemeSettings()
|
||||||
this.checkLocale()
|
this.checkLocale()
|
||||||
|
|
|
@ -37,11 +37,13 @@ export default Vue.extend({
|
||||||
duration: '',
|
duration: '',
|
||||||
description: '',
|
description: '',
|
||||||
watched: false,
|
watched: false,
|
||||||
progressPercentage: 0,
|
watchProgress: 0,
|
||||||
|
publishedText: '',
|
||||||
isLive: false,
|
isLive: false,
|
||||||
isFavorited: false,
|
isFavorited: false,
|
||||||
hideViews: false,
|
hideViews: false,
|
||||||
optionsValues: [
|
optionsValues: [
|
||||||
|
'history',
|
||||||
'openYoutube',
|
'openYoutube',
|
||||||
'copyYoutube',
|
'copyYoutube',
|
||||||
'openYoutubeEmbed',
|
'openYoutubeEmbed',
|
||||||
|
@ -56,6 +58,10 @@ export default Vue.extend({
|
||||||
return this.$store.getters.getUsingElectron
|
return this.$store.getters.getUsingElectron
|
||||||
},
|
},
|
||||||
|
|
||||||
|
historyCache: function () {
|
||||||
|
return this.$store.getters.getHistoryCache
|
||||||
|
},
|
||||||
|
|
||||||
listType: function () {
|
listType: function () {
|
||||||
return this.$store.getters.getListType
|
return this.$store.getters.getListType
|
||||||
},
|
},
|
||||||
|
@ -72,6 +78,12 @@ export default Vue.extend({
|
||||||
return this.$store.getters.getInvidiousInstance
|
return this.$store.getters.getInvidiousInstance
|
||||||
},
|
},
|
||||||
|
|
||||||
|
inHistory: function () {
|
||||||
|
// When in the history page, showing relative dates isn't very useful.
|
||||||
|
// We want to show the exact date instead
|
||||||
|
return this.$router.currentRoute.name === 'history'
|
||||||
|
},
|
||||||
|
|
||||||
invidiousUrl: function () {
|
invidiousUrl: function () {
|
||||||
return `${this.invidiousInstance}/watch?v=${this.id}`
|
return `${this.invidiousInstance}/watch?v=${this.id}`
|
||||||
},
|
},
|
||||||
|
@ -84,8 +96,12 @@ export default Vue.extend({
|
||||||
return `https://www.youtube-nocookie.com/embed/${this.id}`
|
return `https://www.youtube-nocookie.com/embed/${this.id}`
|
||||||
},
|
},
|
||||||
|
|
||||||
|
progressPercentage: function () {
|
||||||
|
return (this.watchProgress / this.data.lengthSeconds) * 100
|
||||||
|
},
|
||||||
|
|
||||||
optionsNames: function () {
|
optionsNames: function () {
|
||||||
return [
|
const names = [
|
||||||
this.$t('Video.Open in YouTube'),
|
this.$t('Video.Open in YouTube'),
|
||||||
this.$t('Video.Copy YouTube Link'),
|
this.$t('Video.Copy YouTube Link'),
|
||||||
this.$t('Video.Open YouTube Embedded Player'),
|
this.$t('Video.Open YouTube Embedded Player'),
|
||||||
|
@ -93,6 +109,14 @@ export default Vue.extend({
|
||||||
this.$t('Video.Open in Invidious'),
|
this.$t('Video.Open in Invidious'),
|
||||||
this.$t('Video.Copy Invidious Link')
|
this.$t('Video.Copy Invidious Link')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (this.watched) {
|
||||||
|
names.unshift(this.$t('Video.Remove From History'))
|
||||||
|
} else {
|
||||||
|
names.unshift(this.$t('Video.Mark As Watched'))
|
||||||
|
}
|
||||||
|
|
||||||
|
return names
|
||||||
},
|
},
|
||||||
|
|
||||||
thumbnail: function () {
|
thumbnail: function () {
|
||||||
|
@ -128,6 +152,8 @@ export default Vue.extend({
|
||||||
} else {
|
} else {
|
||||||
this.parseLocalData()
|
this.parseLocalData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.checkIfWatched()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleSave: function () {
|
toggleSave: function () {
|
||||||
|
@ -139,6 +165,13 @@ export default Vue.extend({
|
||||||
console.log(option)
|
console.log(option)
|
||||||
|
|
||||||
switch (option) {
|
switch (option) {
|
||||||
|
case 'history':
|
||||||
|
if (this.watched) {
|
||||||
|
this.removeFromWatched()
|
||||||
|
} else {
|
||||||
|
this.markAsWatched()
|
||||||
|
}
|
||||||
|
break
|
||||||
case 'copyYoutube':
|
case 'copyYoutube':
|
||||||
navigator.clipboard.writeText(this.youtubeUrl)
|
navigator.clipboard.writeText(this.youtubeUrl)
|
||||||
break
|
break
|
||||||
|
@ -213,7 +246,7 @@ export default Vue.extend({
|
||||||
this.isLive = this.data.liveNow
|
this.isLive = this.data.liveNow
|
||||||
this.viewCount = this.data.viewCount
|
this.viewCount = this.data.viewCount
|
||||||
|
|
||||||
if (typeof (this.data.publishedText) !== 'undefined') {
|
if (typeof (this.data.publishedText) !== 'undefined' && !this.isLive) {
|
||||||
// produces a string according to the template in the locales string
|
// produces a string according to the template in the locales string
|
||||||
this.toLocalePublicationString({
|
this.toLocalePublicationString({
|
||||||
publishText: this.data.publishedText,
|
publishText: this.data.publishedText,
|
||||||
|
@ -221,7 +254,7 @@ export default Vue.extend({
|
||||||
timeStrings: this.$t('Video.Published'),
|
timeStrings: this.$t('Video.Published'),
|
||||||
liveStreamString: this.$t('Video.Watching'),
|
liveStreamString: this.$t('Video.Watching'),
|
||||||
upcomingString: this.$t('Video.Published.Upcoming'),
|
upcomingString: this.$t('Video.Published.Upcoming'),
|
||||||
isLive: this.data.live,
|
isLive: this.isLive,
|
||||||
isUpcoming: this.data.isUpcoming
|
isUpcoming: this.data.isUpcoming
|
||||||
}).then((data) => {
|
}).then((data) => {
|
||||||
this.uploadedTime = data
|
this.uploadedTime = data
|
||||||
|
@ -253,7 +286,7 @@ export default Vue.extend({
|
||||||
this.channelId = this.data.ucid
|
this.channelId = this.data.ucid
|
||||||
this.viewCount = this.data.views
|
this.viewCount = this.data.views
|
||||||
|
|
||||||
// Data is returned as a literal string names 'undefined'
|
// Data is returned as a literal string named 'undefined'
|
||||||
if (this.data.length_seconds !== 'undefined') {
|
if (this.data.length_seconds !== 'undefined') {
|
||||||
this.duration = this.calculateVideoDuration(parseInt(this.data.length_seconds))
|
this.duration = this.calculateVideoDuration(parseInt(this.data.length_seconds))
|
||||||
}
|
}
|
||||||
|
@ -265,7 +298,7 @@ export default Vue.extend({
|
||||||
this.channelId = this.channelId.replace('https://www.youtube.com/channel/', '')
|
this.channelId = this.channelId.replace('https://www.youtube.com/channel/', '')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof (this.data.uploaded_at) !== 'undefined') {
|
if (typeof (this.data.uploaded_at) !== 'undefined' && !this.data.live) {
|
||||||
this.toLocalePublicationString({
|
this.toLocalePublicationString({
|
||||||
publishText: this.data.uploaded_at,
|
publishText: this.data.uploaded_at,
|
||||||
templateString: this.$t('Video.Publicationtemplate'),
|
templateString: this.$t('Video.Publicationtemplate'),
|
||||||
|
@ -293,8 +326,67 @@ export default Vue.extend({
|
||||||
|
|
||||||
this.isLive = this.data.live
|
this.isLive = this.data.live
|
||||||
},
|
},
|
||||||
|
|
||||||
|
checkIfWatched: function () {
|
||||||
|
const historyIndex = this.historyCache.findIndex((video) => {
|
||||||
|
return video.videoId === this.id
|
||||||
|
})
|
||||||
|
|
||||||
|
if (historyIndex !== -1) {
|
||||||
|
this.watched = true
|
||||||
|
this.watchProgress = this.historyCache[historyIndex].watchProgress
|
||||||
|
|
||||||
|
if (this.historyCache[historyIndex].published !== '') {
|
||||||
|
const videoPublished = this.historyCache[historyIndex].published
|
||||||
|
const videoPublishedDate = new Date(videoPublished)
|
||||||
|
this.publishedText = videoPublishedDate.toLocaleDateString()
|
||||||
|
} else {
|
||||||
|
this.publishedText = ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
markAsWatched: 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,
|
||||||
|
watchProgress: 0,
|
||||||
|
timeWatched: new Date().getTime(),
|
||||||
|
isLive: false,
|
||||||
|
paid: false,
|
||||||
|
type: 'video'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateHistory(videoData)
|
||||||
|
|
||||||
|
this.showToast({
|
||||||
|
message: this.$t('Video.Video has been marked as watched')
|
||||||
|
})
|
||||||
|
|
||||||
|
this.watched = true
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFromWatched: function () {
|
||||||
|
this.removeFromHistory(this.id)
|
||||||
|
|
||||||
|
this.showToast({
|
||||||
|
message: this.$t('Video.Video has been removed from your history')
|
||||||
|
})
|
||||||
|
|
||||||
|
this.watched = false
|
||||||
|
},
|
||||||
|
|
||||||
...mapActions([
|
...mapActions([
|
||||||
'toLocalePublicationString'
|
'showToast',
|
||||||
|
'toLocalePublicationString',
|
||||||
|
'updateHistory',
|
||||||
|
'removeFromHistory'
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -84,9 +84,13 @@
|
||||||
<span v-if="viewCount === 1">{{ $t("Video.View") }}</span>
|
<span v-if="viewCount === 1">{{ $t("Video.View") }}</span>
|
||||||
<span v-else-if="parsedViewCount !== ''">{{ $t("Video.Views").toLowerCase() }}</span>
|
<span v-else-if="parsedViewCount !== ''">{{ $t("Video.Views").toLowerCase() }}</span>
|
||||||
<span
|
<span
|
||||||
v-if="uploadedTime !== '' && !isLive"
|
v-if="uploadedTime !== '' && !isLive && !inHistory"
|
||||||
class="uploadedTime"
|
class="uploadedTime"
|
||||||
>• {{ uploadedTime }}</span>
|
>• {{ uploadedTime }}</span>
|
||||||
|
<span
|
||||||
|
v-if="inHistory"
|
||||||
|
class="uploadedTime"
|
||||||
|
>• {{ publishedText }}</span>
|
||||||
<span
|
<span
|
||||||
v-if="isLive"
|
v-if="isLive"
|
||||||
class="viewCount"
|
class="viewCount"
|
||||||
|
|
|
@ -257,6 +257,10 @@ export default Vue.extend({
|
||||||
|
|
||||||
const v = this
|
const v = this
|
||||||
|
|
||||||
|
this.player.on('ready', function () {
|
||||||
|
v.$emit('ready')
|
||||||
|
})
|
||||||
|
|
||||||
this.player.on('ended', function () {
|
this.player.on('ended', function () {
|
||||||
v.$emit('ended')
|
v.$emit('ended')
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<div class="switchColumnGrid">
|
<div class="switchColumnGrid">
|
||||||
<div class="switchColumn">
|
<div class="switchColumn">
|
||||||
<ft-toggle-switch
|
<ft-toggle-switch
|
||||||
v-if="false"
|
|
||||||
label="Remember History"
|
label="Remember History"
|
||||||
:compact="true"
|
:compact="true"
|
||||||
:default-value="rememberHistory"
|
:default-value="rememberHistory"
|
||||||
|
|
|
@ -58,6 +58,7 @@ const router = new Router({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/history',
|
path: '/history',
|
||||||
|
name: 'history',
|
||||||
meta: {
|
meta: {
|
||||||
title: 'History',
|
title: 'History',
|
||||||
icon: 'fa-home'
|
icon: 'fa-home'
|
||||||
|
|
|
@ -38,6 +38,14 @@ $thumbnail-overlay-opacity: 0.85
|
||||||
width: 163px
|
width: 163px
|
||||||
height: auto
|
height: auto
|
||||||
|
|
||||||
|
.videoWatched
|
||||||
|
position: absolute
|
||||||
|
padding: 2px
|
||||||
|
opacity: $thumbnail-overlay-opacity
|
||||||
|
color: var(--primary-text-color)
|
||||||
|
background-color: var(--card-bg-color)
|
||||||
|
pointer-events: none
|
||||||
|
|
||||||
.videoDuration
|
.videoDuration
|
||||||
position: absolute
|
position: absolute
|
||||||
bottom: 4px
|
bottom: 4px
|
||||||
|
@ -66,6 +74,13 @@ $thumbnail-overlay-opacity: 0.85
|
||||||
font-size: 17px
|
font-size: 17px
|
||||||
opacity: $thumbnail-overlay-opacity
|
opacity: $thumbnail-overlay-opacity
|
||||||
|
|
||||||
|
.watchedProgressBar
|
||||||
|
height: 2px
|
||||||
|
position: absolute
|
||||||
|
bottom: 0px
|
||||||
|
background-color: var(--primary-color)
|
||||||
|
z-index: 2
|
||||||
|
|
||||||
.videoCountContainer
|
.videoCountContainer
|
||||||
position: absolute
|
position: absolute
|
||||||
right: 0
|
right: 0
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
import Datastore from 'nedb'
|
||||||
|
|
||||||
|
let dbLocation
|
||||||
|
|
||||||
|
if (window && window.process && window.process.type === 'renderer') {
|
||||||
|
// Electron is being used
|
||||||
|
/* let dbLocation = localStorage.getItem('dbLocation')
|
||||||
|
|
||||||
|
if (dbLocation === null) {
|
||||||
|
const electron = require('electron')
|
||||||
|
dbLocation = electron.remote.app.getPath('userData')
|
||||||
|
} */
|
||||||
|
|
||||||
|
const electron = require('electron')
|
||||||
|
dbLocation = electron.remote.app.getPath('userData')
|
||||||
|
|
||||||
|
dbLocation = dbLocation + '/history.db'
|
||||||
|
} else {
|
||||||
|
dbLocation = 'history.db'
|
||||||
|
}
|
||||||
|
|
||||||
|
const historyDb = new Datastore({
|
||||||
|
filename: dbLocation,
|
||||||
|
autoload: true
|
||||||
|
})
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
historyCache: []
|
||||||
|
}
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
getHistoryCache: () => {
|
||||||
|
return state.historyCache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
grabHistory ({ commit }) {
|
||||||
|
historyDb.find({}).sort({
|
||||||
|
timeWatched: -1
|
||||||
|
}).exec((err, results) => {
|
||||||
|
if (err) {
|
||||||
|
console.log(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
commit('setHistoryCache', results)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
updateHistory ({ dispatch }, videoData) {
|
||||||
|
historyDb.update({ videoId: videoData.videoId }, videoData, { upsert: true }, (err, numReplaced) => {
|
||||||
|
if (!err) {
|
||||||
|
dispatch('grabHistory')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
removeFromHistory ({ dispatch }, videoId) {
|
||||||
|
historyDb.remove({ videoId: videoId }, (err, numReplaced) => {
|
||||||
|
if (!err) {
|
||||||
|
dispatch('grabHistory')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
updateWatchProgress ({ dispatch }, videoData) {
|
||||||
|
historyDb.update({ videoId: videoData.videoId }, { $set: { watchProgress: videoData.watchProgress } }, { upsert: true }, (err, numReplaced) => {
|
||||||
|
if (!err) {
|
||||||
|
dispatch('grabHistory')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
setHistoryCache (state, historyCache) {
|
||||||
|
state.historyCache = historyCache
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state,
|
||||||
|
getters,
|
||||||
|
actions,
|
||||||
|
mutations
|
||||||
|
}
|
|
@ -1,15 +1,59 @@
|
||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
|
import FtLoader from '../../components/ft-loader/ft-loader.vue'
|
||||||
import FtCard from '../../components/ft-card/ft-card.vue'
|
import FtCard from '../../components/ft-card/ft-card.vue'
|
||||||
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
|
import FtFlexBox from '../../components/ft-flex-box/ft-flex-box.vue'
|
||||||
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
|
import FtElementList from '../../components/ft-element-list/ft-element-list.vue'
|
||||||
|
import FtButton from '../../components/ft-button/ft-button.vue'
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'History',
|
name: 'History',
|
||||||
components: {
|
components: {
|
||||||
|
'ft-loader': FtLoader,
|
||||||
'ft-card': FtCard,
|
'ft-card': FtCard,
|
||||||
'ft-flex-box': FtFlexBox,
|
'ft-flex-box': FtFlexBox,
|
||||||
'ft-element-list': FtElementList
|
'ft-element-list': FtElementList,
|
||||||
|
'ft-button': FtButton
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
isLoading: false,
|
||||||
|
dataLimit: 100
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
historyCache: function () {
|
||||||
|
return this.$store.getters.getHistoryCache
|
||||||
|
},
|
||||||
|
|
||||||
|
activeData: function () {
|
||||||
|
if (this.historyCache.length < this.dataLimit) {
|
||||||
|
return this.historyCache
|
||||||
|
} else {
|
||||||
|
return this.historyCache.slice(0, this.dataLimit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
historyCache() {
|
||||||
|
this.isLoading = true
|
||||||
|
setTimeout(() => {
|
||||||
|
this.isLoading = false
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
|
console.log(this.historyCache)
|
||||||
|
|
||||||
|
const limit = sessionStorage.getItem('historyLimit')
|
||||||
|
|
||||||
|
if (limit !== null) {
|
||||||
|
this.dataLimit = limit
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
increaseLimit: function () {
|
||||||
|
this.dataLimit += 100
|
||||||
|
sessionStorage.setItem('historyLimit', this.dataLimit)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,12 +1,35 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ft-card class="card">
|
<ft-loader
|
||||||
|
v-if="isLoading"
|
||||||
|
:fullscreen="true"
|
||||||
|
/>
|
||||||
|
<ft-card
|
||||||
|
v-else
|
||||||
|
class="card"
|
||||||
|
>
|
||||||
<h3>{{ $t("History.History") }}</h3>
|
<h3>{{ $t("History.History") }}</h3>
|
||||||
<ft-flex-box>
|
<ft-flex-box
|
||||||
|
v-if="activeData.length === 0"
|
||||||
|
>
|
||||||
<p class="message">
|
<p class="message">
|
||||||
{{ $t("This part of the app is not ready yet. Come back later when progress has been made.") }}
|
{{ $t("History['Your history list is currently empty.']") }}
|
||||||
</p>
|
</p>
|
||||||
</ft-flex-box>
|
</ft-flex-box>
|
||||||
|
<ft-element-list
|
||||||
|
v-else
|
||||||
|
:data="activeData"
|
||||||
|
/>
|
||||||
|
<ft-flex-box
|
||||||
|
v-if="activeData.length < historyCache.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>
|
</ft-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -47,6 +47,7 @@ export default Vue.extend({
|
||||||
videoViewCount: 0,
|
videoViewCount: 0,
|
||||||
videoLikeCount: 0,
|
videoLikeCount: 0,
|
||||||
videoDislikeCount: 0,
|
videoDislikeCount: 0,
|
||||||
|
videoLengthSeconds: 0,
|
||||||
channelName: '',
|
channelName: '',
|
||||||
channelThumbnail: '',
|
channelThumbnail: '',
|
||||||
channelId: '',
|
channelId: '',
|
||||||
|
@ -72,6 +73,14 @@ export default Vue.extend({
|
||||||
return this.$store.getters.getUsingElectron
|
return this.$store.getters.getUsingElectron
|
||||||
},
|
},
|
||||||
|
|
||||||
|
historyCache: function () {
|
||||||
|
return this.$store.getters.getHistoryCache
|
||||||
|
},
|
||||||
|
|
||||||
|
rememberHistory: function () {
|
||||||
|
return this.$store.getters.getRememberHistory
|
||||||
|
},
|
||||||
|
|
||||||
backendPreference: function () {
|
backendPreference: function () {
|
||||||
return this.$store.getters.getBackendPreference
|
return this.$store.getters.getBackendPreference
|
||||||
},
|
},
|
||||||
|
@ -276,6 +285,7 @@ export default Vue.extend({
|
||||||
this.activeSourceList = this.videoSourceList
|
this.activeSourceList = this.videoSourceList
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
this.videoLengthSeconds = parseInt(result.videoDetails.lengthSeconds)
|
||||||
this.videoSourceList = result.player_response.streamingData.formats
|
this.videoSourceList = result.player_response.streamingData.formats
|
||||||
|
|
||||||
this.audioSourceList = result.player_response.streamingData.adaptiveFormats.filter((format) => {
|
this.audioSourceList = result.player_response.streamingData.adaptiveFormats.filter((format) => {
|
||||||
|
@ -395,6 +405,7 @@ export default Vue.extend({
|
||||||
} else if (this.forceLocalBackendForLegacy) {
|
} else if (this.forceLocalBackendForLegacy) {
|
||||||
this.getLegacyFormats()
|
this.getLegacyFormats()
|
||||||
} else {
|
} else {
|
||||||
|
this.videoLengthSeconds = result.lengthSeconds
|
||||||
this.videoSourceList = result.formatStreams.reverse()
|
this.videoSourceList = result.formatStreams.reverse()
|
||||||
|
|
||||||
this.audioSourceList = result.adaptiveFormats.filter((format) => {
|
this.audioSourceList = result.adaptiveFormats.filter((format) => {
|
||||||
|
@ -441,6 +452,46 @@ export default Vue.extend({
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addToHistory: function (watchProgress) {
|
||||||
|
const videoData = {
|
||||||
|
videoId: this.videoId,
|
||||||
|
title: this.videoTitle,
|
||||||
|
author: this.channelName,
|
||||||
|
authorId: this.channelId,
|
||||||
|
published: this.videoPublished,
|
||||||
|
description: this.videoDescription,
|
||||||
|
viewCount: this.videoViewCount,
|
||||||
|
lengthSeconds: this.videoLengthSeconds,
|
||||||
|
watchProgress: watchProgress,
|
||||||
|
timeWatched: new Date().getTime(),
|
||||||
|
isLive: false,
|
||||||
|
paid: false,
|
||||||
|
type: 'video'
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateHistory(videoData)
|
||||||
|
},
|
||||||
|
|
||||||
|
checkIfWatched: function () {
|
||||||
|
const historyIndex = this.historyCache.findIndex((video) => {
|
||||||
|
return video.videoId === this.videoId
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log(historyIndex)
|
||||||
|
|
||||||
|
if (historyIndex !== -1 && !this.isLive) {
|
||||||
|
console.log(this.historyCache[historyIndex])
|
||||||
|
const watchProgress = this.historyCache[historyIndex].watchProgress
|
||||||
|
this.$refs.videoPlayer.player.currentTime(watchProgress)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.rememberHistory && historyIndex !== -1) {
|
||||||
|
this.addToHistory(this.historyCache[historyIndex].watchProgress)
|
||||||
|
} else if (this.rememberHistory) {
|
||||||
|
this.addToHistory(0)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
checkIfPlaylist: function () {
|
checkIfPlaylist: function () {
|
||||||
if (typeof (this.$route.query) !== 'undefined') {
|
if (typeof (this.$route.query) !== 'undefined') {
|
||||||
this.playlistId = this.$route.query.playlistId
|
this.playlistId = this.$route.query.playlistId
|
||||||
|
@ -630,7 +681,24 @@ export default Vue.extend({
|
||||||
|
|
||||||
...mapActions([
|
...mapActions([
|
||||||
'showToast',
|
'showToast',
|
||||||
'buildVTTFileLocally'
|
'buildVTTFileLocally',
|
||||||
|
'updateHistory',
|
||||||
|
'updateWatchProgress'
|
||||||
])
|
])
|
||||||
|
},
|
||||||
|
beforeRouteLeave: function (to, from, next) {
|
||||||
|
if (this.rememberHistory) {
|
||||||
|
const currentTime = this.$refs.videoPlayer.player.currentTime()
|
||||||
|
console.log(currentTime)
|
||||||
|
const payload = {
|
||||||
|
videoId: this.videoId,
|
||||||
|
watchProgress: currentTime
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('update watch progress')
|
||||||
|
this.updateWatchProgress(payload)
|
||||||
|
}
|
||||||
|
|
||||||
|
next()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
:thumbnail="thumbnail"
|
:thumbnail="thumbnail"
|
||||||
class="videoPlayer"
|
class="videoPlayer"
|
||||||
:class="{ theatrePlayer: useTheatreMode }"
|
:class="{ theatrePlayer: useTheatreMode }"
|
||||||
|
@ready="checkIfWatched"
|
||||||
@ended="handleVideoEnded"
|
@ended="handleVideoEnded"
|
||||||
@error="handleVideoError"
|
@error="handleVideoError"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -95,6 +95,7 @@ History:
|
||||||
# On History Page
|
# On History Page
|
||||||
History: History
|
History: History
|
||||||
Watch History: Watch History
|
Watch History: Watch History
|
||||||
|
Your history list is currently empty.: Your history list is currently empty.
|
||||||
Settings:
|
Settings:
|
||||||
# On Settings Page
|
# On Settings Page
|
||||||
Settings: Settings
|
Settings: Settings
|
||||||
|
@ -264,6 +265,10 @@ Channel:
|
||||||
Channel Description: Channel Description
|
Channel Description: Channel Description
|
||||||
Featured Channels: Featured Channels
|
Featured Channels: Featured Channels
|
||||||
Video:
|
Video:
|
||||||
|
Mark As Watched: Mark As Watched
|
||||||
|
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
|
||||||
Open in YouTube: Open in YouTube
|
Open in YouTube: Open in YouTube
|
||||||
Copy YouTube Link: Copy YouTube Link
|
Copy YouTube Link: Copy YouTube Link
|
||||||
Open YouTube Embedded Player: Open YouTube Embedded Player
|
Open YouTube Embedded Player: Open YouTube Embedded Player
|
||||||
|
|
Loading…
Reference in New Issue