2020-05-23 21:29:42 +00:00
|
|
|
import Vue from 'vue'
|
2021-05-21 23:56:32 +00:00
|
|
|
import { mapActions } from 'vuex'
|
2020-05-23 21:29:42 +00:00
|
|
|
import FtLoader from '../ft-loader/ft-loader.vue'
|
|
|
|
import FtCard from '../ft-card/ft-card.vue'
|
|
|
|
import FtButton from '../ft-button/ft-button.vue'
|
|
|
|
import FtListVideo from '../ft-list-video/ft-list-video.vue'
|
|
|
|
|
|
|
|
import $ from 'jquery'
|
|
|
|
import autolinker from 'autolinker'
|
2021-06-19 18:02:24 +00:00
|
|
|
import { LiveChat } from '@freetube/youtube-chat'
|
2020-05-23 21:29:42 +00:00
|
|
|
|
|
|
|
export default Vue.extend({
|
|
|
|
name: 'WatchVideoLiveChat',
|
|
|
|
components: {
|
|
|
|
'ft-loader': FtLoader,
|
|
|
|
'ft-card': FtCard,
|
|
|
|
'ft-button': FtButton,
|
|
|
|
'ft-list-video': FtListVideo
|
|
|
|
},
|
2020-10-04 18:30:54 +00:00
|
|
|
beforeRouteLeave: function () {
|
|
|
|
this.liveChat.stop()
|
|
|
|
this.hasEnded = true
|
|
|
|
},
|
2020-05-23 21:29:42 +00:00
|
|
|
props: {
|
|
|
|
videoId: {
|
|
|
|
type: String,
|
|
|
|
required: true
|
|
|
|
},
|
|
|
|
channelName: {
|
|
|
|
type: String,
|
|
|
|
required: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
data: function () {
|
|
|
|
return {
|
|
|
|
liveChat: null,
|
|
|
|
isLoading: true,
|
|
|
|
hasError: false,
|
|
|
|
hasEnded: false,
|
|
|
|
showEnableChat: false,
|
|
|
|
errorMessage: '',
|
|
|
|
stayAtBottom: true,
|
|
|
|
showSuperChat: false,
|
|
|
|
showScrollToBottom: false,
|
|
|
|
comments: [],
|
|
|
|
superChatComments: [],
|
|
|
|
superChat: {
|
|
|
|
author: {
|
|
|
|
name: '',
|
|
|
|
thumbnail: ''
|
|
|
|
},
|
|
|
|
message: [
|
|
|
|
''
|
|
|
|
],
|
|
|
|
superChat: {
|
|
|
|
amount: ''
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
usingElectron: function () {
|
|
|
|
return this.$store.getters.getUsingElectron
|
|
|
|
},
|
|
|
|
|
|
|
|
backendPreference: function () {
|
|
|
|
return this.$store.getters.getBackendPreference
|
|
|
|
},
|
|
|
|
|
|
|
|
backendFallback: function () {
|
|
|
|
return this.$store.getters.getBackendFallback
|
|
|
|
},
|
|
|
|
|
|
|
|
chatHeight: function () {
|
|
|
|
if (this.superChatComments.length > 0) {
|
|
|
|
return '390px'
|
|
|
|
} else {
|
|
|
|
return '445px'
|
|
|
|
}
|
2020-10-06 02:27:32 +00:00
|
|
|
},
|
|
|
|
hideLiveChat: function () {
|
|
|
|
return this.$store.getters.getHideLiveChat
|
2020-05-23 21:29:42 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
created: function () {
|
|
|
|
if (!this.usingElectron) {
|
|
|
|
this.hasError = true
|
2020-08-08 02:16:06 +00:00
|
|
|
this.errorMessage = this.$t('Video["Live Chat is currently not supported in this build."]')
|
2020-05-23 21:29:42 +00:00
|
|
|
} else {
|
|
|
|
switch (this.backendPreference) {
|
|
|
|
case 'local':
|
|
|
|
console.log('Getting Chat')
|
|
|
|
this.getLiveChatLocal()
|
|
|
|
break
|
|
|
|
case 'invidious':
|
|
|
|
if (this.backendFallback) {
|
|
|
|
this.getLiveChatLocal()
|
|
|
|
} else {
|
|
|
|
this.hasError = true
|
2020-08-08 02:16:06 +00:00
|
|
|
this.errorMessage = this.$t('Video["Live Chat is currently not supported with the Invidious API. A direct connection to YouTube is required."]')
|
2020-05-23 21:29:42 +00:00
|
|
|
this.showEnableChat = true
|
|
|
|
this.isLoading = false
|
|
|
|
}
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
enableLiveChat: function () {
|
|
|
|
this.hasError = false
|
|
|
|
this.showEnableChat = false
|
|
|
|
this.isLoading = true
|
|
|
|
this.getLiveChatLocal()
|
|
|
|
},
|
|
|
|
|
|
|
|
getLiveChatLocal: function () {
|
|
|
|
this.liveChat = new LiveChat({ liveId: this.videoId })
|
|
|
|
|
|
|
|
this.isLoading = false
|
|
|
|
|
|
|
|
this.liveChat.on('start', (liveId) => {
|
|
|
|
console.log('Live chat is enabled')
|
|
|
|
this.isLoading = false
|
|
|
|
})
|
|
|
|
|
|
|
|
this.liveChat.on('end', (reason) => {
|
|
|
|
console.log('Live chat has ended')
|
|
|
|
console.log(reason)
|
2020-06-03 16:45:01 +00:00
|
|
|
this.hasError = true
|
|
|
|
this.showEnableChat = false
|
2020-08-08 02:16:06 +00:00
|
|
|
this.errorMessage = this.$t('Video["Chat is disabled or the Live Stream has ended."]')
|
2020-05-23 21:29:42 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
this.liveChat.on('error', (err) => {
|
|
|
|
this.hasError = true
|
|
|
|
this.errorMessage = err
|
|
|
|
this.showEnableChat = false
|
|
|
|
})
|
|
|
|
|
|
|
|
this.liveChat.on('comment', (comment) => {
|
|
|
|
this.parseLiveChatComment(comment)
|
|
|
|
})
|
|
|
|
|
|
|
|
this.liveChat.start()
|
|
|
|
},
|
|
|
|
|
|
|
|
parseLiveChatComment: function (comment) {
|
2020-05-28 02:48:41 +00:00
|
|
|
console.log(comment)
|
|
|
|
|
2020-05-23 21:29:42 +00:00
|
|
|
if (this.hasEnded) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
comment.messageHtml = ''
|
|
|
|
|
|
|
|
comment.message.forEach((text) => {
|
2020-05-28 02:48:41 +00:00
|
|
|
if (typeof (text.navigationEndpoint) !== 'undefined') {
|
|
|
|
if (typeof (text.navigationEndpoint.watchEndpoint) !== 'undefined') {
|
2020-12-22 20:34:06 +00:00
|
|
|
const htmlRef = `<a href="https://www.youtube.com/watch?v=${text.navigationEndpoint.watchEndpoint.videoId}">${text.text}</a>`
|
2020-05-28 02:48:41 +00:00
|
|
|
comment.messageHtml = comment.messageHtml + htmlRef
|
|
|
|
} else {
|
|
|
|
comment.messageHtml = comment.messageHtml + text.text
|
|
|
|
}
|
|
|
|
} else if (typeof (text.alt) !== 'undefined') {
|
2021-03-16 10:34:34 +00:00
|
|
|
const htmlImg = `<img src="${text.url}" alt="${text.alt}" height="24" width="24" />`
|
2020-05-28 02:48:41 +00:00
|
|
|
comment.messageHtml = comment.messageHtml + htmlImg
|
|
|
|
} else {
|
|
|
|
comment.messageHtml = comment.messageHtml + text.text
|
|
|
|
}
|
2020-05-23 21:29:42 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
comment.messageHtml = autolinker.link(comment.messageHtml)
|
|
|
|
|
|
|
|
const liveChatComments = $('.liveChatComments')
|
2020-05-28 02:48:41 +00:00
|
|
|
const liveChatMessage = $('.liveChatMessage')
|
2020-05-23 21:29:42 +00:00
|
|
|
|
2020-05-28 02:48:41 +00:00
|
|
|
if (typeof (liveChatComments.get(0)) === 'undefined' && typeof (liveChatMessage.get(0)) === 'undefined') {
|
|
|
|
console.log("Can't find chat object. Stopping chat connection")
|
2020-05-23 21:29:42 +00:00
|
|
|
this.liveChat.stop()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
this.comments.push(comment)
|
2020-10-17 03:01:32 +00:00
|
|
|
console.log(this.comments.length)
|
2020-05-23 21:29:42 +00:00
|
|
|
|
|
|
|
if (typeof (comment.superchat) !== 'undefined') {
|
2021-05-21 23:56:32 +00:00
|
|
|
this.getRandomColorClass().then((data) => {
|
2020-05-23 21:29:42 +00:00
|
|
|
comment.superchat.colorClass = data
|
|
|
|
|
|
|
|
this.superChatComments.unshift(comment)
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
this.removeFromSuperChat(comment.id)
|
|
|
|
}, 120000)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (comment.author.name[0] === 'Ge' || comment.author.name[0] === 'Ne') {
|
2021-05-21 23:56:32 +00:00
|
|
|
this.getRandomColorClass().then((data) => {
|
2020-05-23 21:29:42 +00:00
|
|
|
comment.superChat = {
|
|
|
|
amount: '$5.00',
|
|
|
|
colorClass: data
|
|
|
|
}
|
|
|
|
|
|
|
|
this.superChatComments.unshift(comment)
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
this.removeFromSuperChat(comment.id)
|
|
|
|
}, 120000)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.stayAtBottom) {
|
|
|
|
liveChatComments.animate({ scrollTop: liveChatComments.prop('scrollHeight') })
|
|
|
|
}
|
2020-10-17 03:01:32 +00:00
|
|
|
|
2020-12-17 19:11:13 +00:00
|
|
|
if (this.comments.length > 150 && this.stayAtBottom) {
|
|
|
|
console.log('user is not at bottom')
|
2020-10-17 03:01:32 +00:00
|
|
|
this.comments = this.comments.splice(this.comments.length - 150, this.comments.length)
|
|
|
|
}
|
2020-05-23 21:29:42 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
removeFromSuperChat: function (id) {
|
|
|
|
this.superChatComments = this.superChatComments.filter((comment) => {
|
|
|
|
return comment.id !== id
|
|
|
|
})
|
|
|
|
},
|
|
|
|
|
|
|
|
showSuperChatComment: function (comment) {
|
|
|
|
if (this.superChat.id === comment.id && this.showSuperChat) {
|
|
|
|
this.showSuperChat = false
|
|
|
|
} else {
|
|
|
|
this.superChat = comment
|
|
|
|
this.showSuperChat = true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onScroll: function (event) {
|
|
|
|
const liveChatComments = $('.liveChatComments').get(0)
|
|
|
|
if (event.wheelDelta >= 0 && this.stayAtBottom) {
|
|
|
|
$('.liveChatComments').data('animating', 0)
|
|
|
|
this.stayAtBottom = false
|
|
|
|
|
|
|
|
if (liveChatComments.scrollHeight > liveChatComments.clientHeight) {
|
|
|
|
this.showScrollToBottom = true
|
|
|
|
}
|
|
|
|
} else if (event.wheelDelta < 0 && !this.stayAtBottom) {
|
|
|
|
if ((liveChatComments.scrollHeight - liveChatComments.scrollTop) === liveChatComments.clientHeight) {
|
|
|
|
this.scrollToBottom()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
scrollToBottom: function () {
|
|
|
|
const liveChatComments = $('.liveChatComments')
|
|
|
|
liveChatComments.animate({ scrollTop: liveChatComments.prop('scrollHeight') })
|
|
|
|
this.stayAtBottom = true
|
|
|
|
this.showScrollToBottom = false
|
|
|
|
},
|
|
|
|
|
|
|
|
preventDefault: function (event) {
|
|
|
|
event.stopPropagation()
|
|
|
|
event.preventDefault()
|
2021-05-21 23:56:32 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
...mapActions([
|
|
|
|
'getRandomColorClass'
|
|
|
|
])
|
2020-05-23 21:29:42 +00:00
|
|
|
}
|
|
|
|
})
|