Add chat badges

This commit is contained in:
dragongoose 2023-03-30 10:30:21 -04:00
parent 143e81276b
commit cacec3ad6e
2 changed files with 79 additions and 9 deletions

29
src/components/Badge.vue Normal file
View file

@ -0,0 +1,29 @@
<script lang="ts">
interface Badge {
id: string,
title: string,
setId: string,
version: string,
images: { [k:string]: string }
}
export default {
props: {
badgeInfo: {
type: Object,
}
},
setup(props) {
const data = props.badgeInfo as Badge
return {
src: data.images.image1x,
name: data.title
}
}
}
</script>
<template>
<img :src="src" class="w-5 h-5">
</template>

View file

@ -1,5 +1,14 @@
<script lang="ts"> <script lang="ts">
import { ref, type Ref } from 'vue' import { ref, type Ref } from 'vue'
import BadgeVue from './Badge.vue'
interface Badge {
id: string,
title: string,
setId: string,
version: string,
images: { [k:string]: string }
}
export default { export default {
props: { props: {
@ -13,7 +22,7 @@ export default {
type: String type: String
} }
}, },
setup(props) { async setup(props) {
let messages: Ref< let messages: Ref<
{ {
username: string username: string
@ -23,12 +32,15 @@ export default {
tags: Record<string, string> tags: Record<string, string>
}[] }[]
> = ref([]) > = ref([])
let ws = new WebSocket('ws://localhost:7000')
const badgesFetch = await fetch(`${import.meta.env.VITE_BACKEND_URL}/api/badges?channelName=${props.channelName}`)
let badges: Badge[] = await badgesFetch.json()
return { return {
ws, ws: new WebSocket('ws://localhost:7000'),
messages, messages,
props badges,
props,
} }
}, },
mounted() { mounted() {
@ -40,13 +52,13 @@ export default {
chatStatusMessage.textContent = `Connected to ${this.channelName}` chatStatusMessage.textContent = `Connected to ${this.channelName}`
} else { } else {
this.messages.push(JSON.parse(message.data)) this.messages.push(JSON.parse(message.data))
this.getBadges(JSON.parse(message.data))
this.clearMessages() this.clearMessages()
this.scrollToBottom(chatList) this.scrollToBottom(chatList)
} }
} }
this.ws.onopen = (data) => { this.ws.onopen = (data) => {
console.log(data)
this.ws.send('JOIN ' + this.props.channelName?.toLowerCase()) this.ws.send('JOIN ' + this.props.channelName?.toLowerCase())
} }
}, },
@ -61,7 +73,30 @@ export default {
if (this.messages.length > 50) { if (this.messages.length > 50) {
this.messages.shift this.messages.shift
} }
},
getBadges(message: { username: string, channel: string, message: string, messageType: string, tags: Record<string, string> }) {
let badges = message.tags.badges.split(',')
let formatedBadges = badges.map((badgeWithVersion) => {
const [setId, version] = badgeWithVersion.split('/')
return { setId, version }
})
const foundBadges = []
for(let badgeToFind of formatedBadges) {
const badge = this.badges
.filter((badge) => badge.setId === badgeToFind.setId)
.find((badge) => badge.version === badgeToFind.version);
if(badge)
foundBadges.push(badge)
}
return foundBadges
} }
},
components: {
BadgeVue
} }
} }
</script> </script>
@ -78,12 +113,18 @@ export default {
</li> </li>
<li v-for="message in getChat()" :key="messages.indexOf(message)"> <li v-for="message in getChat()" :key="messages.indexOf(message)">
<div class="text-white inline-flex"> <div class="text-white inline-flex">
<p class="text-sm"> <p class="text-sm items-center">
<ul class="inline-flex space-x-1 pr-1">
<li v-for="badge in getBadges(message)">
<badge-vue :badge-info="badge"></badge-vue>
</li>
</ul>
<strong <strong
:style="message.tags.color ? `color: ${message.tags.color};` : ``" :style="message.tags.color ? `color: ${message.tags.color};` : ``"
class="text-ctp-pink font-bold text-sm" class="text-ctp-pink font-bold">
>{{ message.username }}</strong {{ message.username }}</strong>: {{ message.message }}
>: {{ message.message }}
</p> </p>
</div> </div>
</li> </li>