VOD works now, gonna have to look over changes later

This commit is contained in:
dragongoose
2025-09-15 21:26:50 -04:00
parent 73794bf764
commit 55ca6f35fe
5 changed files with 154 additions and 7 deletions
+1 -1
View File
@@ -102,7 +102,7 @@ export function parseRawMessage(rawMessage: string, allBadges: Badge[]): Message
} }
} }
function parseRawBadges(rb: string, allBadges: Badge[]): Badge[] { export function parseRawBadges(rb: string, allBadges: Badge[]): Badge[] {
const badges = rb.split(',') const badges = rb.split(',')
const formatedBadges = badges.map((badgeWithVersion: string) => { const formatedBadges = badges.map((badgeWithVersion: string) => {
const [setId, version] = badgeWithVersion.split('/') const [setId, version] = badgeWithVersion.split('/')
+143
View File
@@ -0,0 +1,143 @@
<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>
+3 -1
View File
@@ -1,3 +1,5 @@
import type { Badge } from "@/assets/types"
export interface TwitchChatOptions { export interface TwitchChatOptions {
login: { login: {
username: string username: string
@@ -31,5 +33,5 @@ export interface VodMessage {
colorHex: string colorHex: string
} }
offset: number offset: number
badges: VodMessageBadge[] badges: Badge[]
} }
+2 -1
View File
@@ -1,3 +1,4 @@
import type { Badge } from '@/assets/types'
import type { StreamerData } from './Streamer' import type { StreamerData } from './Streamer'
export interface MinifiedCategory { export interface MinifiedCategory {
@@ -47,5 +48,5 @@ export interface VodComment {
messager: MinifiedStreamer messager: MinifiedStreamer
offset: number offset: number
cursor: string cursor: string
badges: VodCommentBadge[] badges: Badge[]
} }
+5 -4
View File
@@ -3,7 +3,7 @@ import { ref, inject } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import VideoPlayer from '@/components/VideoPlayer.vue' import VideoPlayer from '@/components/VideoPlayer.vue'
import TwitchChat from '@/components/TwitchChat.vue' import VodChat from '@/components/VodChat.vue'
import ErrorMessage from '@/components/ErrorMessage.vue' import ErrorMessage from '@/components/ErrorMessage.vue'
import FollowButton from '@/components/FollowButton.vue' import FollowButton from '@/components/FollowButton.vue'
import LoadingScreen from '@/components/LoadingScreen.vue' import LoadingScreen from '@/components/LoadingScreen.vue'
@@ -16,6 +16,7 @@ import type { Video } from '@/types'
import { truncate, abbreviate, getEndpoint } from '@/mixins' import { truncate, abbreviate, getEndpoint } from '@/mixins'
import { getSetting } from '@/settingsManager' import { getSetting } from '@/settingsManager'
interface ChatComponent { interface ChatComponent {
updateVodComments: (time: number) => void updateVodComments: (time: number) => void
} }
@@ -59,7 +60,7 @@ export default {
}, },
components: { components: {
VideoPlayer, VideoPlayer,
TwitchChat, VodChat,
ErrorMessage, ErrorMessage,
FollowButton, FollowButton,
LoadingScreen, LoadingScreen,
@@ -158,11 +159,11 @@ export default {
<about-tab :socials="data.streamer.socials" :about="data.streamer.about"></about-tab> <about-tab :socials="data.streamer.socials" :about="data.streamer.about"></about-tab>
</div> </div>
<twitch-chat <vod-chat
v-if="!getSetting('chatVisible')" v-if="!getSetting('chatVisible')"
:isVod="true" :isVod="true"
:channelName="data.streamer.login" :channelName="data.streamer.login"
ref="chat" ref="chat"
></twitch-chat> ></vod-chat>
</div> </div>
</template> </template>