mirror of
https://github.com/mmjee/Piped-Material.git
synced 2024-12-06 19:26:36 +01:00
Show when and how much you last saw the video + Skip to that time
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<template>
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<span v-bind="attrs" v-on="on">
|
||||
<slot /> {{ timeAgo }}
|
||||
</span>
|
||||
</template>
|
||||
<span>{{ formattedDate }}</span>
|
||||
</v-tooltip>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { LibPiped } from '@/tools/libpiped'
|
||||
|
||||
export default {
|
||||
name: 'ExpandableDate',
|
||||
props: ['date'],
|
||||
computed: {
|
||||
timeAgo () {
|
||||
return LibPiped.timeAgo(this.date)
|
||||
},
|
||||
|
||||
formattedDate () {
|
||||
return LibPiped.formatFullDate(this.date)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -32,7 +32,8 @@ export default {
|
||||
height: Number,
|
||||
width: Number,
|
||||
hideChannel: Boolean,
|
||||
maxHeight: Boolean
|
||||
maxHeight: Boolean,
|
||||
srcProgress: Number
|
||||
},
|
||||
data: () => ({
|
||||
alreadyWatched: false,
|
||||
@@ -43,11 +44,23 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
'video.videoId': 'findIfVideoWatched',
|
||||
'video.url': 'findIfVideoWatched'
|
||||
'video.url': 'findIfVideoWatched',
|
||||
srcProgress: 'findIfVideoWatched'
|
||||
},
|
||||
|
||||
methods: {
|
||||
calcProgress (prog, dur) {
|
||||
return Math.min((prog / dur) * 100, 100)
|
||||
},
|
||||
|
||||
async findIfVideoWatched () {
|
||||
// if it has source progress, it's already seen
|
||||
if (this.srcProgress) {
|
||||
this.alreadyWatched = true
|
||||
this.progress = this.calcProgress(this.srcProgress, this.video.duration)
|
||||
return
|
||||
}
|
||||
|
||||
let videoId
|
||||
if (this.video.videoId) {
|
||||
videoId = this.video.videoId
|
||||
@@ -59,7 +72,7 @@ export default {
|
||||
const lastVideo = await findLastWatch(videoId)
|
||||
if (lastVideo != null) {
|
||||
this.alreadyWatched = true
|
||||
this.progress = lastVideo.progress != null ? Math.min((lastVideo.progress / lastVideo.video.duration) * 100, 100) : 100
|
||||
this.progress = lastVideo.progress != null ? this.calcProgress(lastVideo.progress, lastVideo.video.duration) : 100
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,15 +8,11 @@
|
||||
</v-row>
|
||||
<v-row v-for="(chunk, chunkId) in chunkedByFour" :key="chunkId">
|
||||
<v-col md="3" v-for="doc in chunk" :key="doc._id">
|
||||
<VideoItem :video="doc.video">
|
||||
<v-tooltip bottom>
|
||||
<template v-slot:activator="{ on, attrs }">
|
||||
<span v-bind="attrs" v-on="on">
|
||||
Watched {{ doc.timeAgo }}
|
||||
</span>
|
||||
</template>
|
||||
<span>{{ doc.formattedDate }}</span>
|
||||
</v-tooltip><br />
|
||||
<VideoItem :video="doc.video" :src-progress="doc.progress">
|
||||
<ExpandableDate :date="doc.timestamp">
|
||||
Watched
|
||||
</ExpandableDate>
|
||||
<br />
|
||||
</VideoItem>
|
||||
</v-col>
|
||||
</v-row>
|
||||
@@ -27,11 +23,12 @@
|
||||
import _chunk from 'lodash-es/chunk'
|
||||
|
||||
import { deleteWatchedVideos, getWatchedVideos } from '@/store/watched-videos-db'
|
||||
import { LibPiped } from '@/tools/libpiped'
|
||||
import VideoItem from '@/components/VideoItem'
|
||||
import ExpandableDate from '@/components/ExpandableDate'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ExpandableDate,
|
||||
VideoItem
|
||||
},
|
||||
data: () => ({
|
||||
@@ -47,11 +44,7 @@ export default {
|
||||
|
||||
methods: {
|
||||
async loadData () {
|
||||
this.data = (await getWatchedVideos()).map(doc => {
|
||||
doc.timeAgo = LibPiped.timeAgo(doc.timestamp)
|
||||
doc.formattedDate = LibPiped.formatFullDate(doc.timestamp)
|
||||
return doc
|
||||
})
|
||||
this.data = await getWatchedVideos()
|
||||
this.loaded = true
|
||||
},
|
||||
|
||||
|
||||
+41
-15
@@ -5,7 +5,7 @@
|
||||
<Player
|
||||
ref="player"
|
||||
:video="video"
|
||||
:skip-to-time="'t' in $route.query ? Number($route.query.t) : null"
|
||||
:skip-to-time="skipToTime"
|
||||
:sponsors="sponsors"
|
||||
:selectedAutoLoop="selectedAutoLoop"
|
||||
@videoEnded="videoEnded"
|
||||
@@ -22,13 +22,19 @@
|
||||
{{ $tc('counts.views', video.views, { n: addCommas(video.views) }) }}
|
||||
•
|
||||
{{ video.uploadDate }}
|
||||
<!-- TODO make translatable -->
|
||||
<span v-if="lastWatch">
|
||||
•
|
||||
Last watched till {{ lastWatchDurationH }}
|
||||
<ExpandableDate :date="lastWatch.timestamp" />
|
||||
</span>
|
||||
</v-col>
|
||||
<v-col offset-md="5" md="3" align-self="end">
|
||||
<v-icon>mdi-thumb-up</v-icon>
|
||||
<b class="ml-2">{{ addCommas(video.likes) }}</b>
|
||||
<v-icon class="ml-2">mdi-thumb-down</v-icon>
|
||||
<b class="ml-2">{{ addCommas(video.dislikes) }}</b>
|
||||
<v-btn icon class="ml-2" link :href="'https://youtu.be/' + getVideoId()" @click.prevent="onYTClick" target="_blank">
|
||||
<v-btn icon class="ml-2" link :href="'https://youtu.be/' + videoId" @click.prevent="onYTClick" target="_blank">
|
||||
<v-icon large>
|
||||
mdi-youtube
|
||||
</v-icon>
|
||||
@@ -94,8 +100,9 @@ import Player from '@/components/Player.vue'
|
||||
import VideoItem from '@/components/VideoItem.vue'
|
||||
import ErrorHandler from '@/components/ErrorHandler.vue'
|
||||
import VideoComment from '@/components/VideoComment'
|
||||
import { addWatchedVideo, updateWatchedVideoProgress } from '@/store/watched-videos-db'
|
||||
import { addWatchedVideo, updateWatchedVideoProgress, findLastWatch } from '@/store/watched-videos-db'
|
||||
import SubscriptionButton from '@/components/SubscriptionButton'
|
||||
import ExpandableDate from '@/components/ExpandableDate'
|
||||
|
||||
export default {
|
||||
name: 'WatchVideo',
|
||||
@@ -111,7 +118,8 @@ export default {
|
||||
comments: null,
|
||||
channelId: null,
|
||||
|
||||
dbID: null
|
||||
dbID: null,
|
||||
lastWatch: null
|
||||
}
|
||||
},
|
||||
metaInfo () {
|
||||
@@ -187,7 +195,7 @@ export default {
|
||||
const time = this.$refs.player.getCurrentTime()
|
||||
|
||||
const url = new URL('https://youtube.com/watch')
|
||||
url.searchParams.set('v', this.getVideoId())
|
||||
url.searchParams.set('v', this.videoId)
|
||||
if (Number.isFinite(time)) {
|
||||
url.searchParams.set('t', time.toFixed(0))
|
||||
}
|
||||
@@ -205,7 +213,7 @@ export default {
|
||||
fetchVideo () {
|
||||
return this.$store.dispatch('auth/makeRequest', {
|
||||
method: 'GET',
|
||||
path: '/streams/' + this.getVideoId()
|
||||
path: '/streams/' + this.videoId
|
||||
})
|
||||
},
|
||||
|
||||
@@ -214,7 +222,7 @@ export default {
|
||||
return
|
||||
}
|
||||
this.sponsors = await this.$store.dispatch('auth/makeRequest', {
|
||||
path: '/sponsors/' + this.getVideoId(),
|
||||
path: '/sponsors/' + this.videoId,
|
||||
params: {
|
||||
category: JSON.stringify(this.$store.getters['prefs/getPreference']('selectedSkip', ['sponsor', 'interaction', 'selfpromo', 'music_offtopic']))
|
||||
}
|
||||
@@ -222,7 +230,7 @@ export default {
|
||||
},
|
||||
fetchComments () {
|
||||
return this.$store.dispatch('auth/makeRequest', {
|
||||
path: '/comments/' + this.getVideoId()
|
||||
path: '/comments/' + this.videoId
|
||||
})
|
||||
},
|
||||
|
||||
@@ -234,7 +242,7 @@ export default {
|
||||
|
||||
fetchMoreComments () {
|
||||
this.$store.dispatch('auth/makeRequest', {
|
||||
path: '/nextpage/comments/' + this.getVideoId(),
|
||||
path: '/nextpage/comments/' + this.videoId,
|
||||
params: {
|
||||
nextpage: this.comments.nextpage
|
||||
}
|
||||
@@ -252,8 +260,10 @@ export default {
|
||||
},
|
||||
|
||||
async getVideoData () {
|
||||
this.lastWatch = await findLastWatch(this.videoId)
|
||||
|
||||
const video = await this.fetchVideo()
|
||||
video.videoId = this.getVideoId()
|
||||
video.videoId = this.videoId
|
||||
video.url = this.$route.fullPath
|
||||
this.video = video
|
||||
this.loaded = true
|
||||
@@ -269,16 +279,12 @@ export default {
|
||||
.replaceAll('https://www.youtube.com', '')
|
||||
.replaceAll('\n', '<br>')
|
||||
)
|
||||
this.dbID = await addWatchedVideo(this.video)
|
||||
this.dbID = await addWatchedVideo(video)
|
||||
},
|
||||
getComments () {
|
||||
this.fetchComments().then(data => (this.comments = data))
|
||||
},
|
||||
|
||||
getVideoId () {
|
||||
return this.$route.query.v || this.$route.params.v
|
||||
},
|
||||
|
||||
onTimeUpdate: debounce(function onTimeUpdate (e) {
|
||||
if (this.dbID == null || !this.$refs.player) {
|
||||
return
|
||||
@@ -289,9 +295,29 @@ export default {
|
||||
computed: {
|
||||
isAutoplayEnabled () {
|
||||
return this.$store.getters['prefs/getPreferenceBoolean']('autoplay', false)
|
||||
},
|
||||
videoId () {
|
||||
return this.$route.query.v || this.$route.params.v
|
||||
},
|
||||
skipToTime () {
|
||||
// 't' in $route.query ? Number($route.query.t) : (lastWatch.progress ? lastWatch.progress : undefined)
|
||||
// 1st Priority - t in query
|
||||
// 2nd Priority - Last Watched Progress, if enabled
|
||||
if ('t' in this.$route.query) {
|
||||
return Number(this.$route.query.t)
|
||||
} else if (this.lastWatch && this.lastWatch.progress != null && this.lastWatch.progress !== 0 && this.$store.getters['prefs/getPreferenceBoolean']('skipToLastPoint', true)) {
|
||||
return this.lastWatch.progress
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
|
||||
lastWatchDurationH () {
|
||||
return LibPiped.timeFormat(this.lastWatch.progress)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
ExpandableDate,
|
||||
SubscriptionButton,
|
||||
VideoComment,
|
||||
Player,
|
||||
|
||||
@@ -10,7 +10,8 @@ const PrefsStore = {
|
||||
listen: false,
|
||||
disableLBRY: false,
|
||||
proxyLBRY: true,
|
||||
sponsorblock: true
|
||||
sponsorblock: true,
|
||||
skipToLastPoint: true
|
||||
}
|
||||
}),
|
||||
mutations: {
|
||||
|
||||
@@ -12,11 +12,11 @@ class LibPiped {
|
||||
timeStyle: 'full'
|
||||
})
|
||||
|
||||
timeFormat (duration) {
|
||||
const pad = function (num, size) {
|
||||
return ('000' + num).slice(size * -1)
|
||||
}
|
||||
pad (num, size) {
|
||||
return ('000' + num).slice(size * -1)
|
||||
}
|
||||
|
||||
timeFormat (duration) {
|
||||
const time = parseFloat(duration).toFixed(3)
|
||||
const hours = Math.floor(time / 60 / 60)
|
||||
const minutes = Math.floor(time / 60) % 60
|
||||
@@ -26,7 +26,7 @@ class LibPiped {
|
||||
|
||||
if (hours > 0) str += hours + ':'
|
||||
|
||||
str += pad(minutes, 2) + ':' + pad(seconds, 2)
|
||||
str += this.pad(minutes, 2) + ':' + this.pad(seconds, 2)
|
||||
|
||||
return str
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user