144 lines
3.9 KiB
Vue
144 lines
3.9 KiB
Vue
<script lang="ts">
|
|
import { ref, inject } from 'vue'
|
|
|
|
import BadgeVue from './ChatBadge.vue'
|
|
import { parseRawBadges } from '@/assets/messageParser'
|
|
import { getEndpoint } from '@/mixins'
|
|
|
|
import type { Badge } from '@/assets/types'
|
|
import type { VodComment, VodMessage } from '@/types'
|
|
|
|
|
|
export default {
|
|
props: {
|
|
channelName: {
|
|
type: String
|
|
}
|
|
},
|
|
async setup(props) {
|
|
const messages = ref<VodMessage[]>([])
|
|
const messageCache = ref<VodMessage[]>([])
|
|
const fetchingMessages = false;
|
|
let badges: Badge[] = []
|
|
|
|
await getEndpoint(`api/badges?channelName=${props.channelName}`).then((data) => {
|
|
console.log(data)
|
|
badges = data
|
|
})
|
|
|
|
return {
|
|
messages,
|
|
messageCache,
|
|
fetchingMessages,
|
|
badges,
|
|
}
|
|
},
|
|
async mounted() {
|
|
|
|
|
|
/*
|
|
await getEndpoint(`api/chat/${this.$props.channelName}/history`).then((data) => {
|
|
this.messages = parseChatHistory(data, this.badges)
|
|
})
|
|
*/
|
|
},
|
|
methods: {
|
|
getChat() {
|
|
return this.messages
|
|
},
|
|
scrollToBottom() {
|
|
const el = this.$refs.chatList as Element
|
|
el.scrollTop = el.scrollHeight
|
|
},
|
|
clearMessages() {
|
|
if (this.messages.length > 50) {
|
|
this.messages.splice(0, this.messages.length - 50)
|
|
}
|
|
},
|
|
async updateVodComments(time: number) {
|
|
time = Math.round(time)
|
|
this.clearMessages()
|
|
|
|
for (let i = 0; i < this.messageCache.length; i++) {
|
|
const msg = this.messageCache[i]
|
|
if (!msg) return;
|
|
|
|
if (time >= msg.offset) {
|
|
this.messages.push(msg)
|
|
this.messageCache.splice(i, 1)
|
|
this.scrollToBottom()
|
|
}
|
|
}
|
|
|
|
this.clearMessages()
|
|
|
|
// Only fetch new messages if they are newer than newest message in cache
|
|
const offset = this.messageCache[this.messageCache.length - 1]?.offset ?? 0
|
|
|
|
if ( this.messageCache.length > 5) return;
|
|
|
|
if (this.fetchingMessages) return;
|
|
this.fetchingMessages = true
|
|
try {
|
|
const data: VodMessage[] = await getEndpoint(`api/vods/comments/${this.$route.params.vodID}/${time}` )
|
|
|
|
for (let msg of data) {
|
|
const badgesString = msg.badges.map((data) => { return data.setId + "/" + data.version }).join(',')
|
|
msg.badges = parseRawBadges(badgesString, this.badges)
|
|
}
|
|
|
|
this.messageCache.push(...data)
|
|
} catch (error) {
|
|
throw Error("Error fetching new messages: " + error)
|
|
}
|
|
|
|
this.scrollToBottom()
|
|
this.fetchingMessages = false;
|
|
}
|
|
|
|
},
|
|
components: {
|
|
BadgeVue
|
|
},
|
|
unmounted() {
|
|
this.messages = []
|
|
this.badges = []
|
|
}
|
|
}
|
|
</script>
|
|
<template>
|
|
<div
|
|
class="p-3 bg-crust rounded-lg w-[99vw] md:max-w-[15.625rem] lg:max-w-[20rem] flex flex-col" @PlayerTimeUpdate="updateVodComments"
|
|
>
|
|
<!-- SYSTEM MESSAGES -->
|
|
<ul
|
|
class="overflow-y-scroll overflow-x-hidden space-y-1 whitespace-pre-wrap h-[46.875rem]"
|
|
ref="chatList"
|
|
>
|
|
<li>
|
|
<p ref="initConnectingStatus" class="text-gray-500 text-sm italic">
|
|
{{ $t('chat.connecting', { username: channelName }) }}
|
|
</p>
|
|
</li>
|
|
<li v-for="message in getChat()" :key="messages.indexOf(message)">
|
|
<div class="text-contrast inline-flex">
|
|
<!-- CHAT MESSAGE-->
|
|
<div class="text-sm items-center">
|
|
<ul v-if="message.badges.length > 0" class="inline-flex space-x-1 pr-1">
|
|
<li v-for="badge in message.badges" :key="badge.setId">
|
|
<badge-vue :badge-info="badge"></badge-vue>
|
|
</li>
|
|
</ul>
|
|
|
|
<p class="inline">
|
|
<strong :style="message.messager.colorHex? `color: ${message.messager.colorHex};` : ``" class="text-purple font-bold">
|
|
{{ message.messager.name }}</strong
|
|
>: {{ message.message }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</template>
|